Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.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 PDO语句比MySQL CLI长400倍_Php_Mysql_Pdo - Fatal编程技术网

Php PDO语句比MySQL CLI长400倍

Php PDO语句比MySQL CLI长400倍,php,mysql,pdo,Php,Mysql,Pdo,我正在运行一个PDO准备的语句,以便从约6k行的表中进行选择。由于WHERE语句有~5k个PID,这个特定的查询最终返回所有的行。该表在pId列上也有一个索引 SELECT * FROM table_a WHERE pId in (?, ? ,? ....) 此查询在php中运行需要4.5秒,在MySQL CLI中运行需要0.01秒。PHP和MySQL的EXPLAIN语句是相同的,都是而不是使用pId上的索引。我认为这是因为MySQL知道它正在返回整个表,并且不需要使用索引 我知道预先准备好的

我正在运行一个PDO准备的语句,以便从约6k行的表中进行选择。由于WHERE语句有~5k个PID,这个特定的查询最终返回所有的行。该表在pId列上也有一个索引

SELECT * FROM table_a WHERE pId in (?, ? ,? ....)
此查询在php中运行需要4.5秒,在MySQL CLI中运行需要0.01秒。PHP和MySQL的EXPLAIN语句是相同的,都是而不是使用pId上的索引。我认为这是因为MySQL知道它正在返回整个表,并且不需要使用索引

我知道预先准备好的语句会有一些开销,但我在别处运行了一个非常类似的查询(不同的表名),而且不会花那么长的时间(大约9秒)。有什么想法吗

PHP版本:5.5


MySql版本:5.6

我怀疑在获取行、返回的行数,而不是语句中的5000多个bind占位符时速度较慢<代码>pId在(?、、…、?)中

我的建议是测试只返回一行,提供一个已知存在/返回行的值,然后提供4999+个已知不存在/不返回行的值

例如,如果我们知道表中的最高pId值,请使用高于该值的值,为这样的语句提供绑定值

 ... pId IN ( ? , ? , ? , ... , ? )
因此,结果相当于运行

 ... pId IN ( 99999999 , 99999998 , 99999997 , ... , 42 )
这和我们运行的结果是一样的

 ... pId IN ( 42 )
我们的期望是只返回一行(pId=42)

然后比较(5000+返回一行的绑定值)与返回一行的两个绑定值的计时

 ... pId IN ( 99999999 , 42 )
并查看性能是否存在显著差异

(对于5000+个绑定值,还有更多的工作要做,但我不希望有太大的差异,但应该进行测试


仔细想想,使用所有现有的绑定值设置测试可能会更容易,只需在查询的末尾添加
limit2
(我不确定MySQL是否对
limit2
有一些性能增强)

最好添加一个条件,如
和pId*10=420

目标是提供大量绑定值,但只返回一行或两行


另一个测试是返回整组行,但只使用两个绑定值。可能是返回5000+行的范围条件

查询可以是:

 ... pId >= ? AND pId <= ? 

…pId>=?pId在
in
子句中使用的
pId
是否来自另一个查询?如果是,您可以使用
exists重写
PDO必须建立连接才能执行操作。将pooling设置为true,并尝试执行此语句几次。我正在质疑4.5秒内包含了什么。这是m吗仅对
execute
进行测量。这包括
bindValue
调用的时间吗?
prepare
调用的时间吗?这包括
bindResult
调用的时间,以及获取和处理行的时间吗?PDO是使用服务器端prepare,还是在客户端使用模拟prepare?为了比较,什么是值在没有bindValue调用的情况下被合并到SQL文本中的时间?另外,当不涉及查询缓存时,CLI的执行时间是多少
然后将其强制转换为INT作为
3
。当然它会运行得更快。但您是否也会得到相同的结果?:-)PDO存在一个问题。下面是一个相关的未解决问题:…我明白了-您已经发现了。“是什么导致速度变慢,绑定值的数量还是返回的行的数量?”-两者都是-因此是O(n²)@PaulSpiegel:需要通过一些测试来确认……我的怀疑是绑定值的数量对总运行时间的影响不大。我在这个答案中建议的测试应该指出哪个因素(绑定值的数量,或者返回的行数)实际影响了运行时间。(我假设绑定值是由
bindValue
提供的,而不是
bindParam
,或者这可能没有什么区别。)我的评论是基于测试的。执行一个愚蠢的测试查询,比如
select*from t,其中id在(?,,,,,,)或者1=1 limit$numRows
。从1000个参数开始,限制1000个。然后增加参数的数量。您将看到使用相同的结果集增加获取时间。@PaulSpiegel:并且测试是使用
bindValue
而不是
bindParam
,对吗?它们是使用
exec($params)执行的
。但你认为这有什么关系呢?大部分时间都花在
fetch()
fetchAll()
上。