PDO Statement Taking 400x Longer Than MySQL CLI [duplicate]

给你一囗甜甜゛ 提交于 2019-12-23 16:28:50

问题


I am running a PDO prepared statement to select from a table of around ~6k rows. This particular query ends up returning all of the rows due to the WHERE statement which has ~5k pIds. The table has an index on the pId column as well.

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

This query takes 4.5 seconds to run in php and when run in the MySQL CLI it takes .01 seconds. The EXPLAIN statement for PHP and MySQL are the same, both are NOT using the index on pId. I think this is due to the fact that MySQL is aware that it is returning the entire table and does not need to use the index.

I know there's some overhead with prepared statements but I am running a very similar query (different table name) elsewhere and it's not taking close to as long (~.9 seconds). Any ideas?

PHP Version: 5.5

MySql Version: 5.6


回答1:


I suspect the slowness is in fetching the rows, the number of rows being returned, rather than the 5000+ bind placeholders in the statement. pId IN ( ? , ? , ... , ? )

My suggestion would be to test returning only a single row, supply one value that is known to exist/return a row, and then 4999+ values that are known not to exist/not to return a row.

For example, if we know the highest pId value in the table, use values higher than that, supply bind values for a statement like this

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

so the result would be equivalent to running

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

which would be the same result we would get running

 ... pId IN ( 42 )

Our expectation would be to return just one row ( pId = 42 ).

Then compare the timing of that ( 5000+ bind values returning 1 row ) to two bind values returning a single row

 ... pId IN ( 99999999 , 42 )

And see if there is a significant difference in performance.

(There's more work to do with 5000+ bind values, but I wouldn't expect a huge difference, but it should be tested.


Thinking on it a bit, it might be easier to setup a test using all the existing bind values, and just adding LIMIT 2 to the end of the query. (I'm not sure if MySQL has some performance enhancements for LIMIT 2.

It maybe better to add a condition like AND pId * 10 = 420

The goal is to supply a whole slew of bind values but only return one or two rows.


Another test would be to return a whole slew of rows, but using only a couple of bind values. Maybe a range condition that returns 5000+ rows.

The query could be:

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

with a large enough range between the provided values that we get in the neighborhood of 5000 rows.

And compare performance.

My prediction (guess?) is that performance will be correlated more with the number of rows returned, rather than the number of bind values.


I'm not sure if this is an answer to your question, but it's the approach I would take to answer the question ... "what is causing this to be slow, the number of bind values, or the number of rows returned?"



来源:https://stackoverflow.com/questions/50375815/pdo-statement-taking-400x-longer-than-mysql-cli

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!