Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP一般原则:一个大的SQL调用更好还是很多小的SQL调用更好_Php_Mysql_Optimization_Lamp - Fatal编程技术网

PHP一般原则:一个大的SQL调用更好还是很多小的SQL调用更好

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

这是一个优化问题,涉及:第一原则。。想象一下,我正在做一个重大的举重比较。。30k文件与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
     }   
 }
更新:如果您总是知道$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,我将在上面添加一些内容。