【问题标题】:How to decrease time of loop如何减少循环时间
【发布时间】:2018-01-07 17:35:13
【问题描述】:

我有一个包含大约 4,000 个名称的数据库表。我需要阅读这些内容,循环浏览它们并在另一个表中使用这些名称以及用户输入的 id 创建条目。最多可以有 20 个 id。我已经编写了这段代码,但是如果在三分钟后仍在运行,所以我停止了它。我希望有一种方法可以对其进行编码以减少时间。它将位于最大执行时间为 60 秒的共享服务器上,因此不会花费更长的时间。这就是我所拥有的。任何人都可以找到提高速度的方法吗?

    $mysql_query = "select id from main_table";
    $post = array('0' => 1, '1' => 2); //up to 20 entries
    $cnt = count($post);
    $str = '';

    while ($item = mysql_fetch_array($mysql_query)) {
      for ($i = 0; $i < $cnt; ++$i)  {
        $str .= "('" . $item['id'] . "', '" . $post[$i] . "'),";
      }    
    }  
    $str = substr($str, 0 -1);
    mysql_query("insert into next_table values" . $str );

【问题讨论】:

  • 为什么不做一个INSERT INTO ... SELECT FROM? 让数据库在一个查询中完成所有工作......您应该能够将新ID注入其中
  • 您不能对查询字符串运行提取循环。你需要先做一个 mysql_query() 。可能是为什么需要这么长时间。
  • 不会因为您没有先运行查询,mysql_fetch_array 总是返回 false 吗?所以循环将永远运行
  • 是的,它应该显示一个错误。但是他发布的代码是不正确的。
  • 不要不要使用mysql_*接口;切换到mysqli_*PDO

标签: php mysql sql performance loops


【解决方案1】:

这是一种根本不需要 PHP 循环和字符串连接的解决方案。但是你仍然需要 PHP 代码(留作练习)来转换它:

$post = array(1, 2, 3);

进入这个:

SELECT 1 AS val UNION ALL
SELECT 2        UNION ALL
SELECT 3

这是您需要执行的一个查询:

INSERT INTO next_table
SELECT main_table.id, userval.val
FROM main_table
JOIN (
    SELECT 1 AS val UNION ALL
    SELECT 2        UNION ALL
    SELECT 3
) AS userval

剧透:

$post = array(1, 2, 3);
$sql = array_reduce($post, function($acc, $value){
  $cur = $acc === "" ?
    sprintf("SELECT %d AS val", $value) :
    sprintf("\nUNION ALL SELECT %d", $value);
  return $acc . $cur;
}, "");

【讨论】:

    【解决方案2】:

    如果您找不到其他解决方案如何减少执行时间,即。任何类型的优化,然后您都可以尝试减少一次处理的记录数

    在执行时间限制内对可以处理的id数量进行block。

    // get the very last inserted record from next_table
    // and select reasonable amount of records from main_table to process
    $mysql_query = "SELECT id FROM main_table 
    WHERE id > (SELECT id FROM next_table MAX(id) LIMIT 1) 
    LIMIT 500)"; // change the 500 to whatever
    

    然后调用脚本的次数与等待处理的数据一样多。

    【讨论】:

      【解决方案3】:

      这是基于 Salman A 的答案的新代码。大约需要 3 秒才能完成。优秀的。我将发布新代码以防有人在某个时候需要它。

          $mysql_query = mysql_query("select id from main_table");
          $post = array('0' => 1, '1' => 2); //up to 20 entries
          $cnt = count($post);
          $str = '';
      
          if ($cnt == 1) {
              $str .= "SELECT " . $post[0] . " AS val ";
          } else {    
              $str .= "SELECT " . $post[0] .  " AS val UNION ALL ";
      
              for ($i = 1; $i < $cnt; ++$i) {              
                  $str .= " SELECT " . $post[$i] . " UNION ALL ";
              }
              $str = substr($str, 0, -11);
          }
      
          $raw = "INSERT INTO next_table SELECT main_table.id, userval.val
            FROM main_table JOIN ( " . $str . " ) AS userval ";             
      
          mysql_query($raw);      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-04
        • 1970-01-01
        • 2016-07-04
        • 2013-10-21
        • 2022-01-04
        • 2018-03-27
        • 2021-11-03
        • 2021-12-11
        相关资源
        最近更新 更多