这是一个优化问题RE:第一原则..想象一下,我正在做一个重大的提升比较.. 30k文件vs 30k数据库条目..是一个最大的进程效率做一个大的MySQL进入一个数组然后循环物理文件检查与数组相比,或者最好循环访问文件,然后一次一行MySQL调用..
这里有一些伪代码可以帮助解释:
//is this faster?
foreach($recursiveFileList as $fullpath){
$Record = $db->queryrow("SELECT * FROM files WHERE fullpath='".$fullpath."'");
//do some $Record logic
}
//or is this faster
$BigList = array();
$db->query("SELECT * FROM files");
while($Record = $db->rows()){
$BigList[$Record['fullpath']] = $Record;
}
foreach($recursiveFileList as $fullpath){
if (isset($BigList[$fullpath])){
$Record = $BigList[$fullpath];
//do some $Record logic
}
}
答案 0 :(得分:1)
更新:如果您总是知道您的$ recursiveFileList是表的100%,那么每行执行一次查询将是不必要的开销。在这种情况下,只需使用
SELECT * FROM files
。
我不会使用你展示的两种风格中的任何一种。
第一种样式为每个单独的完整路径运行一个单独的SQL查询。这会导致SQL解析,优化等的一些开销。请记住,MySQL不具备从一次类似查询的调用到下一次调用的记忆查询优化的能力。它每次分析并执行查询优化。开销相对较小,但却相加。
第二种样式显示从表中获取所有行,并在应用程序层中对其进行排序。这有一个很多的开销,因为通常您的$recursiveFileList
可能只匹配表中的1%或0.1%或更小部分的行。我已经看到通过网络传输过多数据的情况实际上耗尽了1Gbps网络交换机,这为应用程序的每秒请求设置了上限。
明智地使用查询条件和索引让RDBMS检查并仅返回匹配的行。
您展示的两种风格并非唯一选项。我建议使用范围查询来匹配单个查询中的多个文件fullpath
值。
$sql = "SELECT * FROM files WHERE fullpath IN ("
. array_fill(0, count($recursiveFileList), "?") . ")";
$stmt = $pdo->prepare($sql);
$stmt->execute($recursiveFileList);
while ($row = $stmt->fetch()) {
//do some $Record logic
}
注意我还使用带有?
参数占位符的预准备查询,然后在调用execute()
时单独传递完整路径值数组。 PDO对此很好,因为您可以只传递一个数组,并且数组元素与参数占位符匹配。
在这种情况下,这也解决了SQL注入的风险。