2017-07-12 17 views
0

我使用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 = $query->fetch(); $a++) { 
    $query2 = $db->prepare("INSERT INTO d_chart (date,room,status) VALUES (? + INTERVAL ? DAY,?,0)"); 
    $query2->execute(array($thisDay,$i,$result['room'])); 
    } 
} 

這個代碼的運行速度太慢,如何更好的代碼,快速,<2秒。

回答

0

您應該能夠通過使用INSERT...SELECT查詢,使這個顯著簡單(假設MySQL的)

// 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(); 
} 

如果d_room.activ有索引,這將是更快。

+0

- >結果每個房間只有一天,我預計每個房間的下一個1000天。例如:我有48個房間,我想爲每個房間插入1000天。 – danihandiki

+0

@danihandiki這很奇怪。由於'for'循環,查詢應執行1000次。你確定你正在使用我的確切代碼? – Phil

+0

@danihandiki即使日期不是每次增加一天,每個房間應該有1000條記錄,每個記錄都在同一天。 – Phil

-1
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'])); 

     } 
+1

'$ result'從哪裏來? – Phil

+0

@B。 I.薩迪的結果是一樣的,每個房間只有一天,我預計每個房間的下一個1000天。例如:我有48個房間,我想爲每個房間插入1000天。 – danihandiki

+0

希望它能起作用。 –

0
  1. 不要運行完全相同的查詢1000次!
  2. 檢查您的索引以加快查詢速度。
  3. 準備查詢,然後在循環中執行它。這是準備的。
  4. 分別在循環前後使用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 

正如你所看到的,循環現在更加緊湊得多 - 總是首先要加快代碼速度。

+0

可否請您編寫代碼,以便我可以比較和學習。 – danihandiki

+0

已編輯 - 查看評論回答。 – Mike

1

我不知道你爲什麼要這樣做。但是,我建議您不要將這些模糊數據存儲在您的數據庫中,因爲如果時間和空間限制是問題,還有其他方式可以執行此類任務。正如您所說的< 2秒,那麼即使在本地機器上存儲該大結果也不會少於30秒。

所以你能做的僅僅是一個結果存儲在數據庫中的哪些如下:

$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'])); 
} 

,如果你想檢索接下來的1000天的數據則只是從數據庫讀取並顯示單日數據在客戶端使用一些數學計算在未來1000天的結果,這將比任何事情都快得多。

但是,你應該解釋你做這麼重要的任務的目的是什麼,以便你能得到更好的答案。

+0

我學會了製作房間狀態系統。系統通知日期哪些房間可用或空了。如果狀態= 1,則意味着可用 – danihandiki

+0

我建議您存儲空間不可用或不可用的日期。例如,今天是12-07,房間預定爲25-07,那麼你應該只存儲這個12-07的日期,在另一個持續時間列中,你應該存儲持續時間,直到房間從13天的例子中可用因此在持續時間欄中存儲13個。因此,如果用戶從12-07到13天的持續時間查詢房間,則會導致「可用」或「不可用」。或者你可能會想一個更好的解決方案。 – sagar

+0

非常感謝,我會測試它並比較 – danihandiki