使用MySQL数据库PHP中的计数填充List

时间:2013-04-02 17:23:42

标签: php mysql filtering

我正在尝试根据从MySQL数据库中的列中使用通配符选择的结果创建列表。我能够做到,但它似乎很慢,可能是错误的方式。这是我现在正在修改的代码

$optarr = array("leather", "cruise", "tint", "sunroof", "moonroof", "navigation", "antilock");
 foreach ($optarr as $i) {
    $refquery = "SELECT stock, COUNT(stock) FROM vehicle_list AND options LIKE '%$i%'"; 
    $refresult = mysql_query($refquery) or die(mysql_error());
    $row = mysql_fetch_array($refresult);

    if ($row['COUNT(stock)'] != '0') {
    echo "".ucfirst($i)." (".$row['COUNT(stock)'].")<br />";
    }
}

这将输出以下内容

Leather(234)
Cruise(343)
Tint(231)
Sunroof(343)
.....

这个列表最终会有大约20-30个不同的过滤器选项,现在在4-5我可以看到实质性的延迟。我做错了什么,只是不知道是什么。也许是整个方法?

数据库中的选项列是由@符号分隔的整个文本块,因此我使用Like通配符来提取车辆选项。

谢谢!

5 个答案:

答案 0 :(得分:1)

在foreach循环之前进行数据库调用。这是在每个循环上调用数据库,并且将按预期缓慢。

答案 1 :(得分:0)

从标准化和优化的角度来看,您应该将选项放在单独的表格中,然后使用表格将vehicle_list表格链接到您的选项。

这将允许您使用连接和分组来仅使用一个查询而不是使用双面的查询来获取所需的结果(即使使用索引也不是一个好主意)。

http://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html

答案 2 :(得分:0)

你必须加入表格

 $optarr = array("leather", "cruise", "tint", "sunroof", "moonroof", "navigation", "antilock");
     foreach ($optarr as $i) {
    $refquery = "SELECT stock, COUNT(stock)  FROM vehicle_list 
    LEFT JOIN options ON vehicle_list.stock=options.stock LIKE '%$i%'"; 
    $refresult = mysql_query($refquery) or die(mysql_error());
    $row = mysql_fetch_array($refresult);

    if ($row['COUNT(stock)'] != '0') {
    echo "".ucfirst($i)." (".$row['COUNT(stock)'].")<br />";
    }

答案 3 :(得分:0)

您似乎在$optarr

中每次出现一个新查询

您可以先尝试创建条件列表,然后触发单个查询

这样的东西
$optarr = array("leather", "cruise", "tint", "sunroof", "moonroof", "navigation", "antilock");
 $strCondition = NULL;
 foreach ($optarr as $i) {
    $strCondition .= ( true == is_null(strCondition ) )? "LIKE '%$i%'" : "OR LIKE '%$i%'"; 
}

if( false != $strCondition ) {
    $refresult = mysql_query( 'SELECT stock, COUNT(stock) FROM vehicle_list AND options ' . $strCondition ) or die(mysql_error());
     while( $row = mysql_fetch_array($refresult) )
     {
         if ($row['COUNT(stock)'] != '0') {
         echo "".ucfirst($i)." (".$row['COUNT(stock)'].")<br />";
     }
}

可能有一些syntax errors,因为我没有测试它:p。

上面的方法会给出一个performance gain,一般来说,你应该按照你希望的方式存储表中的值(我建议只添加一个新的列条件,比如'leather',cruise' ..等)

答案 4 :(得分:0)

您应该规范化您的选项,使它们位于与vehicle_list表相关的表中。这将使你的生活更加轻松。

所以说你有这样的表vehicle_options

vehicle_option_id -> primary_key, autoincrement
vehicle_id -> foreign key to vehicle_list table
option -> text string describing option

所有三个字段都需要一个索引。

然后,您可以针对此表从单个查询中获取计数。在这种情况下,您根本不需要查询vehicle_list。

SELECT option, COUNT (vehicle_option_id) AS `option_count` FROM
vehicle_options
GROUP BY option

为了进一步规范化,您甚至可以考虑使用另一个实际包含可用选项描述的表选项,并将vehicle_options表简单地用作多对多连接表。使用此架构,您的表将如下所示:

vehicle_options

vehicle_id -> foreign key to vehicle_list table
option_id -> foreign key to option table

两个字段都有一个主键

options

option_id -> primary_key, autoincrement
option -> text string describing option

如果要将其用于分组/排序目的,您可能需要索引选项

您的查询将如下所示:

SELECT o.option AS `option`, COUNT (vo.option_id) AS `option_count`
FROM vehicle_options AS vo
INNER JOIN options AS o
GROUP BY `option`