0

我正在读取一个包含 1000 行的 csv 文件。我对每一行执行一个查询,这里是查询:

$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 行被搜索和常量ref意味着它应该很快它使用索引

现在在我的循环中,我有以下内容:

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

为什么需要很长时间?CSV 文件中只有 1000 行,对查询运行解释似乎足够快。

它会在 5-10 分钟后超时,但不应该花那么长时间,我不知道是什么问题。

有一点需要注意foo3表包含700万条记录。

4

4 回答 4

1

您是否确定脚本实际上可以检测到行尾?如果没有,那就试试

ini_set('auto_detect_line_endings',TRUE);

而且您似乎没有指定数据的长度,请尝试以下操作:

$line = fgetcsv($handle, 1000)

在仔细查看 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 />';
}

另一方面,您的主要问题可能是查询本身。也许我给你的方法可以带来更快的方法。

于 2013-03-07T15:39:57.877 回答
0

尝试在控制台中启动该过程。见 exec() 之后。该进程可以将有关进程状态的数据放入共享存储(mysql/file/etc...)中。

于 2013-03-07T15:27:45.037 回答
0

仅仅因为查询“使用”索引,并不意味着“它应该很快”。速度取决于是否可以使用“正确”索引以及查询是否被构造为高效。

例如,您的查询使用:

WHERE foo1.Text LIKE :txt

如果 foo1 中有很多行和/或 foo1.Text 很大(即 TEXT 类型字段)并且 :txt 可能以 % 开头,那么这意味着主表将无法使用索引。

此外,所有必需的连接索引可能都没有到位。例如,从您的查询中可以明显看出 foo3.ID 字段不是主键。

为了更好地回答“为什么需要很长时间?”这个问题,我需要更多关于 foo1/2/3 表结构的信息。

于 2013-03-07T15:34:50.790 回答
0

是否有可能只有其中一行有问题?我将从 CLI 运行它开始;将输出更改为仅记录行的索引和执行时间。这应该有助于澄清问题。

于 2013-03-07T16:54:05.107 回答