这个问题在这里已经有答案了:
为什么在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
1条答案
按热度按时间6pp0gazn1#
我怀疑慢是在获取行时,返回的行数,而不是语句中5000+个bind占位符。
pId IN ( ? , ? , ... , ? )
我的建议是测试只返回一行,提供一个已知存在/返回行的值,然后提供4999+个已知不存在/不返回行的值。例如,如果我们知道表中的最高pid值,则使用高于该值的值,为这样的语句提供bind值
所以结果相当于跑步
这和我们跑步的结果是一样的
我们期望只返回一行(pid=42)。
然后比较(5000+个bind值返回一行)和两个bind值返回一行的时间
看看他们的表现是否有显著差异。
(对于5000+个绑定值,还有更多的工作要做,但我并不期望有很大的区别,但应该进行测试。
仔细想想,使用所有现有的绑定值来设置测试可能更容易,只需添加
LIMIT 2
到查询的结尾(我不确定mysql是否有一些性能增强LIMIT 2
.最好加一个条件,比如
AND pId * 10 = 420
目标是提供一系列绑定值,但只返回一行或两行。另一个测试是返回一系列行,但只使用几个绑定值。可能是返回5000+行的范围条件。
查询可以是:
在提供的值之间有足够大的范围,我们在5000行附近得到。
并比较性能。
我的预测(猜测?)是,性能将更多地与返回的行数相关,而不是与绑定值的数量相关。
我不确定这是否是对你问题的回答,但这是我回答问题的方法……”是什么原因导致速度变慢,是绑定值的数量还是返回的行的数量?”