PHP一般原则:一个大的SQL调用更好还是很多小的SQL调用更好
这是一个优化问题,涉及:第一原则。。想象一下,我正在做一个重大的举重比较。。30k文件与30k数据库条目。。将一个大型MySQL放入一个数组,然后循环检查物理文件和数组,这是最高效的处理方式吗?还是最好循环检查文件,然后一次一个执行一行MySQL调用 下面是一些帮助解释的伪代码:PHP一般原则:一个大的SQL调用更好还是很多小的SQL调用更好,php,mysql,optimization,lamp,Php,Mysql,Optimization,Lamp,这是一个优化问题,涉及:第一原则。。想象一下,我正在做一个重大的举重比较。。30k文件与30k数据库条目。。将一个大型MySQL放入一个数组,然后循环检查物理文件和数组,这是最高效的处理方式吗?还是最好循环检查文件,然后一次一个执行一行MySQL调用 下面是一些帮助解释的伪代码: //is this faster? foreach($recursiveFileList as $fullpath){ $Record = $db->queryrow("SELECT * FROM
//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
}
}
更新:如果您总是知道$recursiveFileList是表的100%,那么每行执行一个查询将是不必要的开销。在这种情况下,只需使用SELECT*fromfiles
你展示的两种风格我都不会用
第一种样式为每个完整路径运行一个单独的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注入的风险。您的SQL server与文件服务器不同吗?如果不是,那就没关系了。MySQL仍然在使用文件在服务器上存储这些数据,它只是为您提供了一个接口来推断这些数据。这主要是一个微优化。它是一个本地主机数据库-一个LAMP服务器,也没有存储在MySQL中的文件-纯粹的路径名-那么它真的没有多大区别。如果您愿意,您可以连接第二台计算机并使其成为您的SQL server,然后您可以将大量处理工作卸载到SQL server上,这将有助于降低开销。但是,就目前而言,这将是一个最小的性能增益。为什么不试试呢?您在这里使用什么接口连接到MySQL?您没有使用占位符,占位符通常表示您做了一些非常错误的事情,并使自己面临严重的风险。谢谢,我完全理解
索引的作用,但是第三种方式(我曾经想到过)不会与最大允许数据包
相冲突吗。类似地,讨论注入风险也是OT。而且匹配的可能性约为100%,这是MySQL文件表中所有内容的$recursiveFileList
-OP试图澄清这一点-30k vs 30kOkay,我将在上面添加一些内容。