2013-03-07 102 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开始执行此操作;将输出更改为只记录行的索引和执行所花费的时间。这应该有助于澄清问题。