如何解决我缓慢的代码(使用PHP-PDO)
我使用的是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 = $
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']));
}