如何解决我缓慢的代码(使用PHP-PDO)

如何解决我缓慢的代码(使用PHP-PDO),php,pdo,Php,Pdo,我使用的是PHP PDO, 这是代码: for ($i = 0; $i < 1000; $i++) { //select room and insert to chart $thisDay=date ("Y-m-d"); $query = $db->prepare("SELECT room FROM d_room WHERE activ=1 ORDER BY room"); $query->execute(); for($a = 1; $result = $

我使用的是PHP PDO, 这是代码:

for ($i = 0; $i < 1000; $i++) {
  //select room and insert to chart
  $thisDay=date ("Y-m-d");
  $query = $db->prepare("SELECT room FROM d_room WHERE activ=1 ORDER BY room");
  $query->execute();
  for($a = 1; $result = $query->fetch(); $a++) {
    $query2 = $db->prepare("INSERT INTO d_chart (date,room,status) VALUES (? + INTERVAL ? DAY,?,0)");
    $query2->execute(array($thisDay,$i,$result['room']));
  }
}
($i=0;$i<1000;$i++)的
{
//选择房间并插入到图表中
$thisDay=日期(“Y-m-d”);
$query=$db->prepare(“从d_房间中选择房间,其中activ=1按房间排序”);
$query->execute();
对于($a=1;$result=$query->fetch();$a++){
$query2=$db->prepare(“插入d_图表(日期、房间、状态)值(?+间隔?天,0)”;
$query2->execute(数组($thisDay,$i,$result['room']);
}
}
这段代码运行得太慢了,如何使代码变得更好更快,<2秒。

我看不出有任何理由在循环中数千次运行此查询。因为它正在执行相同的查询。将查询置于循环之外。
    I am not seeing any reason to run this query thousands time inside the loop. Because it is executing the same query. Put the query outside the loop.





    <?php
        //select room and insert to chart
        $thisDay = date("Y-m-d");
        $query   = $db->prepare("SELECT room FROM d_room WHERE activ=1 ORDER BY room");
        $query->execute();
        $query2 = $db->prepare("INSERT INTO d_chart (date,room,status) VALUES (? + INTERVAL ? DAY,?,0)");
$result = $query->fetch();
        for ($i = 0; $i < 1000; $i++) {

            $query2->execute(array($thisDay, $i, $result['room']));

        }
  • 不要运行完全相同的查询1000次
  • 检查索引以加快查询速度
  • 准备查询,然后在循环中执行它。这就是我们的准备
  • 在循环之前和之后分别使用PDO::beginTransaction和PDO::commit。索引更新可能很昂贵,而且一次更新所有索引会更快
  • 这至少应该使它尽可能快

    $thisDay = date ("Y-m-d");         // Take this outside the loop
    $query   = $db->prepare("SELECT room FROM d_room WHERE activ=1 ORDER BY room");
    $query2  = $db->prepare("INSERT INTO d_chart (date,room,status) VALUES (? + INTERVAL ? DAY,?,0)");     //  Prepare this once
    
    $query->execute();               // Just run this once
    $rowset = $query->fetchAll ();   //  Put into an array to re-loop without querying again
    
    $db->beginTransaction ();        //  Will update indices in bulk - faster
    
    for ($i = 0; $i < 1000; $i++)
    {
        //select room and insert to chart
        foreach ($rowset as $result)
            $query2->execute(array($thisDay,$i,$result['room']));
    }
    $db->commit ();                   //  Apply changes
    
    $thisDay=日期(“Y-m-d”);//把这个放在圈外
    $query=$db->prepare(“从d_房间中选择房间,其中activ=1按房间排序”);
    $query2=$db->prepare(“插入到d_图表(日期、房间、状态)值(?+间隔?天,0)”;//准备一下
    $query->execute();//只运行一次
    $rowset=$query->fetchAll();//放入数组以重新循环,而无需再次查询
    $db->beginTransaction();//将批量更新索引-更快
    对于($i=0;$i<1000;$i++)
    {
    //选择房间并插入到图表中
    foreach($result作为行集)
    $query2->execute(数组($thisDay,$i,$result['room']);
    }
    $db->commit();//应用更改
    

    正如您所看到的,循环现在变得越来越紧密了——总是第一个寻求代码加速的地方。

    您应该能够通过使用查询(假设使用MySQL)使这一过程变得更加简单

    //确保看到可能发生的任何错误
    ini_设置(“显示错误”、“打开”);
    错误报告(E_全部);
    $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);
    $thisDay=日期('Y-m-d');
    $stmt=$db->prepare('插入d_图表(日期、房间、状态)
    选择(:thisDay+间隔:天),房间,0
    从d_房间开始,活动=1');//没有必要对这些结果进行排序
    $stmt->bindParam(':thisDay',$thisDay);
    $stmt->bindParam(':days',$i,PDO::PARAM_INT);
    对于($i=0;$i<1000;$i++){
    $stmt->execute();
    }
    

    如果
    d_room.activ
    有一个索引,这会更快。

    我不知道你为什么要这样做。但是,我建议您不要将这些模糊数据存储在数据库中,因为如果存在时间和空间限制的问题,还有其他方法可以完成这些任务。正如您所说的准备(“从d_room中选择房间,其中activ=1房间订单”); $query->execute(); $result=$query->fetchAll(PDO::FETCH_ASSOC);//在这里存储结果将减少在循环内获取数据的时间,因为脚本不需要从服务器一次又一次地获取数据。 $query=$db->prepare(“插入d_图表(日期、房间、状态)值(?+间隔?天,0)”; 对于($i=0;$iexecute(数组($thisDay,$i,$result[$i]['room')); }
    如果您想检索下一个1000天的数据,那么只需从数据库中获取一天的数据,并在客户端使用下一个1000天的数学计算来显示结果,这将比任何事情都快得多


    但是,你应该解释一下你做这么大的任务的目的是什么,这样你才能得到更好的答案。

    哪里来的
    $result
    呢?@B.I.Sadi结果是一样的,每个房间只有一天,我预计每个房间接下来的1000天。例如:我有48个房间,我想为每个房间插入1000天。-->结果是打开的每个房间只有一天,我预计每个房间接下来会有1000天。例如:我有48个房间,我想为每个房间插入1000天。@danihandiki这很奇怪。由于
    for
    循环,查询应该执行1000次。你确定你使用的是我的确切代码吗?@danihandiki即使日期没有每次增加一天,你也可以每个房间都应该有1000条记录,每个房间都在同一天。@Danishandiki还确保如果出现错误,您能够看到任何错误。请参阅我的更新答案以获取一个示例。我使用Xampp v 3.2.1,php 5.2.0。如果有此效果,我将学习创建房间状态系统。系统会通知在日期内哪些房间可用或空。如果状态=1,则表示n可用我建议您存储房间不可用或不可用的天数。例如,今天是12-07,房间预订时间是25-07,那么您应该只存储该12-07日期,并且在另一个持续时间列中,您应该存储持续时间,直到房间可用为止。示例中为13天,所以在持续时间列中存储13。因此,如果用户查询从2007年12月到未来13天的房间,结果将是“可用”或“不可用”。或者您可能会考虑更好的解决方案。是的,您应该这样做。如果需要帮助,您可以从我处获得帮助。:)已编辑-请参阅已审阅的答案。
    // Make sure you see any errors that might occur
    ini_set('display_errors', 'On');
    error_reporting(E_ALL);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $thisDay = date('Y-m-d');
    $stmt = $db->prepare('INSERT INTO d_chart (date, room, status)
        SELECT (:thisDay + INTERVAL :days DAY), room, 0
        FROM d_room WHERE activ = 1'); // there's no need to order these results
    $stmt->bindParam(':thisDay', $thisDay);
    $stmt->bindParam(':days', $i, PDO::PARAM_INT);
    for ($i = 0; $i < 1000; $i++) {
        $stmt->execute();
    }
    
    $thisDay=date ("Y-m-d");
    $query = $db->prepare("SELECT room FROM d_room WHERE activ=1 ORDER BY room");
    $query->execute();
    $result = $query->fetchAll(PDO::FETCH_ASSOC); // storing result here would reduce some time to fetch the data inside loop because your script would not require to get the data again and again from server.
    $query = $db->prepare("INSERT INTO d_chart (date,room,status) VALUES (? + INTERVAL ? DAY,?,0)");
    for($i=0; $i<sizeof($result);$i++)
    {
      $query->execute(array($thisDay,$i,$result[$i]['room']));
    }