PHP takes 90x longer to run query than MySQL client

前端 未结 4 614
轻奢々
轻奢々 2020-12-10 02:46

I\'m running a MySQL query via a command-line PHP script (prepared query using PDO on the mysqlnd driver). It\'s a simple query with a single left-join, returning 100 rows

相关标签:
4条回答
  • 2020-12-10 03:05

    I had the same problem. Same query was acting differently when launched from cli and from PHP. Explain in cli mentioned correct index usage, in PHP there was nothing. As I have found, the problem was type casting, in my case it was datetime. After I have specifically cast type for compared value eg. where datetime_column > cast('2014-01-12 12:30:01' as datetime) everything works.

    0 讨论(0)
  • 2020-12-10 03:09

    PDO uses resources to manipulates row results. Par that with an interpreted language (PHP) and you will have script that takes longer to process than it does for MySQL to return your results.

    NOTE: Using mysql_select_db() or mysqli_select_db() is much faster than PDO.

    To learn more about faster PHP Queries, see: PHP: What's the fastest way to query MySQL? Because PDO is painfully slow

    0 讨论(0)
  • 2020-12-10 03:15

    Giving a very belated update on this question:

    I've not found the cause, but it turns out the EXPLAIN was different in PHP versus on the CLI. I'm not sure if any aspect of the connection would cause MySQL to choose to use a different field for the index, because as far as I know those things shouldn't be related; but alas, PHP's EXPLAIN showed that the proper index was not being used, while the CLI's did.

    The solution in this (baffling) case is to use index hinting. See the 'FROM' line in this modified query from my example:

    SELECT HEX(al.uuid) hexUUID, al.created_on,
        IFNULL(al.state, 'ON') actionType, pp.publishers_id publisher_id,
        pp.products_id product_id, al.action_id, al.last_updated
    FROM ActionAPI.actionLists al USE INDEX (created_on)
    LEFT JOIN ActionAPI.publishers_products pp
        ON al.publisher_product_id = pp.id
    WHERE (al.test IS NULL OR al.test = 0)
        AND (al.created_on >= :since OR al.last_updated >= :since)
    ORDER BY created_on ASC
    LIMIT :skip, 100;
    

    Hope this helps someone!

    0 讨论(0)
  • 2020-12-10 03:28

    When your connecting on the command line its VERY likely to be using a different charicter set that when your connecting with PHP.

    When your asking it to use an index, It will and because the char sets are close enough to not cause an issue (at a guess ? It depends on your set up of the table and columns)

    Try thowing some unicode charicters in there and it will likely start to return bad results.

    Make sure the the char set matches on the connection, the table and the column for best results. If They cant be done, The connection is the most important

    UTF-8 vs Latin1 mysql, indexes not used on utf-8

    Has some more info

    0 讨论(0)
提交回复
热议问题