0

我有一个包含 ~100000 行和 ~150 列数据的数据库,格式如下:

data_id               data_name  monthly_data1  monthly_data2  monthly_data3    ""    ""
      0     product1_data-item1             20             30             10    ""    ""
      1     product1 data-item2             10             30             20    ""    ""
      2     product1 data-item3              9             10             23    ""    ""
      3     product2 data-item1             40             13             12    ""    ""
      4     product2 data-item2             31             12             32    ""    ""
      5     product2 data-item3             23             49             23    ""    ""

上面的数据集是数据的基本样本,实际上有超过 2000 个产品,每个产品有 50+ 个数据项(约 100,000 行)和约 140 列数据,即年度数据。

我需要在数据库中搜索每个数据项 - 每个产品(即每一行),并确定每个数据项的 month_data1 到 month_data140 列中的值是否在该特定数据项的预定最小/最大范围内.

这是我的代码格式,它正在运行,只是非常缓慢,大约需要 20 秒才能完成每年对每种产品的所有 50 次检查。

$numberProducts = 2000;
$numberLineItems = 50;
$numberMonths = 140;

for($m=0;$m<$numberMonths;$m++){
    for($p=0;$p$numberProducts;$p++){
      $dataMonth = 'data_month'.$m+1;
          $q="SELECT $dataMonth FROM product_table WHERE data_id='".($p*$numberLineItems)."'";
          $q=mysql_query($q);
          while($row=mysql_fetch_assoc($q)){
              $dataVal = $row[$dataMonth];
          }
          mysql_free_result($q);
          if(($dataVal>=$dataMin1)&&($dataVal<=$dataMax1)){
              $q="SELECT $dataMonth FROM product_table WHERE data_id='".($p*$numberLineItems+1)."'";
              $q=mysql_query($q);
              while($row=mysql_fetch_assoc($q)){
                  $dataVal = $row[$dataMonth];
              }
              mysql_free_result($q);
              if(($dataVal>=$dataMin2)&&($dataVal<=$dataMax2)){
                  $q="SELECT $dataMonth FROM product_table WHERE data_id='".($p*$numberLineItems+2)."'";
                  $q=mysql_query($q);
                  while($row=mysql_fetch_assoc($q)){
                      $dataVal = $row[$dataMonth];
                  }
                  mysql_free_result($q);
                  if(($dataVal>=$dataMin3)&&($dataVal<=$dataMax3)){
.
.
.

等等。一直到每个产品每个月的第 50 个数据项,检查该产品的该数据项的月值是否在预定范围内 --- 预定范围(dataMin/dataMax)不同每个产品的每个单独的数据项,但产品之间的每个特定数据项相同。

我正在寻找一种方法来加速代码、不同的查询组合、服务器设置、循环样式等,这可能有助于优化事情并缩短输出所需的几秒钟。任何想法,将不胜感激。

我的第一个想法是更改 select 语句以选择整个数据库 $q = "SELECT * FROM product_table"; 并将数据放入多维数组中以进行最小/最大检查并避免 14,000,000 次查询,但我遇到了“内存不足”限制。

必须有更好的方法...

4

2 回答 2

0

您可以尝试,如下所示...我未经测试就发送,如果您发现任何语法错误,请尝试更正这些语法错误...

 $numberMonths = 140;
 $minRange = 20;
 $maxRange = 35;
 $dataItemArray = array();

 $q=mysql_query("SELECT * FROM product_table");
 while($row=mysql_fetch_assoc($q)){
         for($i = 1 ; $i <= numberMonths; $i++){
            $nowColumn = monthly_data$i;
            if(($row[$nowColumn] >= $minRange) AND ($row[$nowColumn] <= $maxRange))
                $dataItemArray = $row['data_name']
         }  

      }
于 2013-01-27T12:27:31.813 回答
0

这是一种方法:

for ($i = 1; $i <= 50; $i++) {

    $$min = 'dataMin' . $i;
    $$max = 'dataMax' . $i;

    $dataMonth = 'data_month' . $i;

    //Query to get all the data_id's that fall in the given range
    //If you know that many of your data_month values will be in the min max range, 
    //you can use the opposite of this query.
    //i.e select those data_ids that are not in the range -- this result set 
    //will be significantly smaller and will consume much less time and memory
    /*
     * eg: 
     * $res = mysql_query('SELECT data_id 
                            FROM product_table 
                            WHERE ' . $dataMonth . ' > ' . $$max . ' OR ' . $dataMonth . ' < ' . $$min);
     */
    $res = mysql_query('SELECT data_id 
                            FROM product_table 
                            WHERE ' . $dataMonth . ' <= ' . $$max . ' AND ' . $dataMonth . ' >= ' . $$min);
    if (mysql_num_rows($res) > 0) {
        while ($row = mysql_fetch_assoc($res)) {
            //this arr will contain the data_ids who are in the given range for the moth $dataMonth
            $finalArr[$dataMonth][] = $row['data_id'];
        }
    }
    mysql_free_result($res);
    //$finalArr will have months as keys and data_ids who have the value in the specified range
}
于 2013-01-27T12:52:33.357 回答