pdo语句比mysql cli长400倍

00jrzges  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(203)

这个问题在这里已经有答案了

为什么在php和mysql中使用pdo的某些类型的预处理查询速度很慢(3个答案)
两年前关门了。
我正在运行一个pdo prepared语句,从大约6k行的表中进行选择。由于where语句有~5k个PID,这个特定的查询最终返回所有的行。该表在pid列上也有一个索引。

SELECT * FROM table_a WHERE pId in (?, ? ,? ....)

这个查询在php中运行需要4.5秒,在mysql cli中运行需要0.01秒。php和mysql的explain语句是相同的,都没有使用pid上的索引。我认为这是因为mysql知道它正在返回整个表,不需要使用索引。
我知道prepared语句会有一些开销,但是我在别处运行了一个非常类似的查询(不同的表名),而且不会花费那么长的时间(大约0.9秒)。有什么想法吗?
php版本:5.5
mysql版本:5.6

6pp0gazn

6pp0gazn1#

我怀疑慢是在获取行时,返回的行数,而不是语句中5000+个bind占位符。 pId IN ( ? , ? , ... , ? ) 我的建议是测试只返回一行,提供一个已知存在/返回行的值,然后提供4999+个已知不存在/不返回行的值。
例如,如果我们知道表中的最高pid值,则使用高于该值的值,为这样的语句提供bind值

... pId IN ( ? , ? , ? , ... , ? )

所以结果相当于跑步

... pId IN ( 99999999 , 99999998 , 99999997 , ... , 42 )

这和我们跑步的结果是一样的

... pId IN ( 42 )

我们期望只返回一行(pid=42)。
然后比较(5000+个bind值返回一行)和两个bind值返回一行的时间

... pId IN ( 99999999 , 42 )

看看他们的表现是否有显著差异。
(对于5000+个绑定值,还有更多的工作要做,但我并不期望有很大的区别,但应该进行测试。
仔细想想,使用所有现有的绑定值来设置测试可能更容易,只需添加 LIMIT 2 到查询的结尾(我不确定mysql是否有一些性能增强 LIMIT 2 .
最好加一个条件,比如 AND pId * 10 = 420 目标是提供一系列绑定值,但只返回一行或两行。
另一个测试是返回一系列行,但只使用几个绑定值。可能是返回5000+行的范围条件。
查询可以是:

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

在提供的值之间有足够大的范围,我们在5000行附近得到。
并比较性能。
我的预测(猜测?)是,性能将更多地与返回的行数相关,而不是与绑定值的数量相关。
我不确定这是否是对你问题的回答,但这是我回答问题的方法……”是什么原因导致速度变慢,是绑定值的数量还是返回的行的数量?”

相关问题