2013-03-07 246 views
0

我正在讀取包含1000行的csv文件。我執行一個查詢的每一行,這裏是查詢:PHP腳本超時時間太長

$foobar = 
    SELECT foo1.ID 
    FROM foo1 
    INNER JOIN foo2 ON foo2.ID = foo1.ID 
    LEFT JOIN foo3 bar1 ON bar1.ID = foo1.ID 
    LEFT JOIN foo3 bar2 ON bar2.ID = foo1.ID 
    WHERE foo1.Text LIKE :txt 
    AND foo2.col1 = 31 AND bar1.col1 = 138 AND bar2.col1 = 271 
    AND (bar1.col2 = "" OR bar1.col2 IS NULL) 
    AND (bar2.col2 = "" OR bar2.col2 IS NULL) 

這個解釋和被搜查只有100行並不斷裁判這意味着它要快,它使用指標返回。

現在,在我的循環,我有以下幾點:

while ($line = fgetcsv($handle)){ 
    $foobar->execute(); 
    $data = $foobar->fetchAll(\PDO::FETCH_ASSOC); 
    var_dump($data); echo '<br /><br />'; 
} 

爲什麼它需要很長時間? CSV文件中只有1000行,並且在查詢上運行解釋似乎足夠快。

它喜歡5-10分鐘後超時,但它不應該花那麼長時間我不知道最新的問題。

有一點需要注意foo3表包含萬條記錄。

+0

嗯......它運行緩慢,因爲你發出了對數據庫的1,000個查詢? – 2013-03-07 15:33:12

+0

好想,但1000分鐘10分鐘? – Jonast92 2013-03-07 15:40:48

回答

1

您是否確定該腳本實際上可以檢測到行尾?如果沒有,那麼嘗試

ini_set('auto_detect_line_endings',TRUE); 

而且你似乎並不被指定數據的長度,你可以試試:

$line = fgetcsv($handle, 1000) 

又過了smort外觀上的PHP手冊,最使用的方法是檢查

while (($line = fgetcsv($handle, 1000)) !== FALSE) 

我也注意到你加入了一個\到您使用fetchall聲明,試試這個來代替:

fetchAll(PDO::FETCH_ASSOC) 

你也可以這樣做與數據合作:

if($result = $stmt->fetchAll(PDO::FETCH_ASSOC)) 
{ 
    foreach($result as $res) 
    { 
     foreach($res as $key=>$val) 
     { 
      $temp[$key] = utf8_encode($val); 
     } 
     array_push($array, $temp); 
    } 
    var_dump($array); 
    echo '<br /><br />'; 
} 

你的主要問題可能是,在另一方面,查詢本身。也許我給你的方法會導致更快的方式。

+0

非常感謝你($ line = fgetcsv($ handle)!== FALSE)這麼做。不知道!== false會立即執行。 – GGio 2013-03-07 15:52:27

+0

太棒了!樂意效勞。 – Jonast92 2013-03-07 15:52:52

0

嘗試在控制檯中啓動進程。在exec()後面查看。該過程可以將數據放入共享存儲(mysql/file/etc ...)中,以瞭解進程狀態。

0

僅僅因爲查詢「使用」索引,並不意味着「它應該很快」。速度取決於「正確的」索引是否可用以及查詢是否構建爲有效。

例如,您的查詢使用:

WHERE foo1.Text LIKE :txt 

如果有foo1很多行和/或foo1.Text是一個大的(即TEXT類型字段)和:TXT也許以一個%,那麼這意味着主表將無法使用索引。

此外,所有必需的連接索引可能不適用。例如,從您的查詢中可以明顯看出,foo3.ID字段不是主鍵。

爲了更好地回答「爲什麼需要很長時間?」這個問題,我需要更多關於表foo1/2/3。

0

是否有可能僅有一行出現問題?我會從CLI開始執行此操作;將輸出更改爲只記錄行的索引和執行所花費的時間。這應該有助於澄清問題。