【问题标题】:Populate a List with counts from MySQL database PHP使用 MySQL 数据库 PHP 中的计数填充列表
【发布时间】:2014-05-18 21:07:23
【问题描述】:

我正在尝试根据从 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 通配符来提取车辆选项。

谢谢!

【问题讨论】:

    标签: php mysql filtering


    【解决方案1】:

    在 foreach 循环之前进行数据库调用。这是在每个循环上调用数据库,并且会像预期的那样慢。

    【讨论】:

    • 不是每次都得调用才能分别统计吗?
    • 没有。你调用数据库然后循环结果
    【解决方案2】:

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

    这将允许您使用 join 和 group by 仅使用一个查询来获得所需的结果,而不是使用双面类似的大量查询(即使使用索引也不是一个好主意)。

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

    【讨论】:

      【解决方案3】:

      您似乎正在为$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,一般来说,你应该以你希望检索它们的方式在表中存储值(我建议添加一个新的列条件,只有值像'皮革',巡航'..等)

      【讨论】:

        【解决方案4】:

        你必须加入表格

         $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 />";
            }
        

        【讨论】:

          【解决方案5】:

          您可能应该规范化您的选项,以便它们位于与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
          

          如果您打算将其用于分组/排序目的,您可能需要一个 index on 选项

          您的查询将如下所示:

          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`
          

          【讨论】:

            猜你喜欢
            • 2017-11-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多