Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 PDOStatement::fetchAll()太慢_Php_Performance_Pdo_Fetchall - Fatal编程技术网

Php PDOStatement::fetchAll()太慢

Php PDOStatement::fetchAll()太慢,php,performance,pdo,fetchall,Php,Performance,Pdo,Fetchall,我遇到了一个超慢的PDOStatement::fetchAll()语句,这简直让我发疯。 我的查询在0.1秒内运行。同样在MySQL终端中,我在不到0.1秒的时间内将输出显示在屏幕上。但是在PDO语句上运行fetchAll()需要2.5秒 // $_DB is my PDO class instance. $tStart = microtime(true); $q = $_DB->prepare('SELECT id FROM ... WHERE ... LIMIT 1000'); $q-

我遇到了一个超慢的PDOStatement::fetchAll()语句,这简直让我发疯。 我的查询在0.1秒内运行。同样在MySQL终端中,我在不到0.1秒的时间内将输出显示在屏幕上。但是在PDO语句上运行fetchAll()需要2.5秒

// $_DB is my PDO class instance.
$tStart = microtime(true);
$q = $_DB->prepare('SELECT id FROM ... WHERE ... LIMIT 1000');
$q->execute($aArgs);
var_dump(round(microtime(true) - $tStart, 5));
$aIDsFiltered = $q->fetchAll(PDO::FETCH_COLUMN, 0);
var_dump(round(microtime(true) - $tStart, 5));exit;
这将产生:

float(0.0612)
float(2.58708)
好吧,说真的?如何在MySQL控制台中在不到0.1秒的时间内获得结果,而PHP需要2.5秒才能获取1000个结果并将其放入一个简单的数组中?来吧,一个简单的for循环将1000个数字逐个放入一个数组需要0.001秒。。。!!! 我错过了什么?我可以使用什么作为替代方案?我已经在谷歌上搜索过了,但我找不到解决方案:(提前谢谢

编辑:fetchAll()的持续时间不仅与返回结果的数量有关……还与$aArgs的大小有关。不发送参数会使fetchAll()在0.01秒内返回,即使有50K个结果!输入execute()调用47K参数会使fetchAll()返回然后运行120秒。但并不是因为创建了大查询字符串(顺便问一下,execute()是否会这样做?),因为相同的47K个参数,但限制为1K个结果只需要2.5秒。。。 正如所建议的,我已经验证了PDO的解释输出与使用MySQL控制台的解释输出是相同的。我也没有看到MySQL工作得很努力,是Apache进程(因此PHP)一直在消耗CPU。 另外:使用较旧的mysql_*接口,获取结果需要0.03秒

背景信息 对于好奇的人:

  • 它是本地MySQL 5.5数据库,所以不是远程服务器
  • PHP版本:5.4.4
  • 这里的用例是,系统中有许多过滤器(一个过滤器=一个数据库查询),以用户最喜欢的顺序运行,其中每个过滤器从上一次过滤器运行中获得匹配项的ID,并且它应该返回剩余匹配项的ID(希望这是清楚的)。通过这种方式,过滤器最终用于选择与所有过滤器匹配的数据库条目的一小部分
  • 有时我实际上要返回47K个结果,然后延迟2.1分钟,而查询只需不到1秒,这在我的情况下是不可接受的
  • 我知道,通过将多个过滤器组合到一个数据库查询中,我可以大大减少结果的数量。但是,过滤器是由用户选择的(因此无限制的组合),他们可以对不同的数据库表进行连接和检查,最后但并非最不重要的是,他们希望看到每个筛选器返回多少结果的统计信息

您的查询的SQL可以告诉我们一些信息。尝试运行
解释选择…
并查看查询计划。检查索引是否正确使用,等等

但是,简单执行调用和fetchAll调用之间的区别可能取决于几个因素:

  • 底层驱动程序的性能-您使用的是
    mysqlnd
    驱动程序还是旧版本
  • 结果集的大小—将所有数据加载到数组结构将占用内存和时间
    • 值得注意的是,
      PDOStatement->execute
      无论如何只返回一个布尔值

首先,我要确保您有足够的内存和分配给PHP的CPU,并检查PHP正在使用的mysql驱动程序。它应该是
mysqlnd

,PHP必须将数据从数据库的存储器传输到它自己的内存中并在那里进行后期处理。这取决于PHP和数据库之间的连接方式,这可能会导致一些延迟。我们无法确定2.5秒在您的情况下是否合理,因为我们不知道设置的详细信息。deceze是正确的,但仍然要说的是,通过正确的设置,PHP使用的时间将与
mysql
控制台客户端的时间相当。但请记住,控制台客户端将ot做一个fetchAll。它会一个接一个地迭代结果集。这会节省大量内存。你应该对PHP做同样的操作,否则结果就不可比较。谢谢!对“正确设置”有什么建议吗?它只是一个本地MySQL(5.5.31)数据库…删除我在init上设置的特殊PDO标志没有效果,所以我没有做任何奇怪的事情。哦,使用fetch()循环并不会加快速度…那么问题是如何修复“然而”之后的所有问题直接跟在您引用的文本后面…--问题仍然是为什么PDO能够在短时间内完美地处理50K个参数,能够在fetchAll()中完美地获取50K个结果时间很短,但根本无法处理两者的组合,而本机mysql客户端和PHP的mysql_*函数完全没有问题……相关:-感谢您花时间回答!但是,查询不是问题。它在不到0.1秒的时间内完成(不仅在PHP中,也在控制台中)。我切换到mysqlnd驱动程序,没有什么区别。查询中显示的大小是1000个结果(只是数字ID)。在现实生活中,可以返回47K个结果(当然问题会变得更大)。为什么要以答案的形式发布你的无聊想法?问题下的注释非常适合他们。