为啥这个 mySQL 查询非常慢?

Posted

技术标签:

【中文标题】为啥这个 mySQL 查询非常慢?【英文标题】:Why is this mySQL query extremely slow?为什么这个 mySQL 查询非常慢? 【发布时间】:2013-07-09 13:33:24 【问题描述】:

给定一个名为“orders_products”的 mysql 表,其中包含以下相关字段:

products_id orders_id

两个字段都被索引。

我正在运行以下查询:

SELECT products_id, count( products_id ) AS counter
FROM orders_products
WHERE orders_id
IN (
  SELECT DISTINCT orders_id
  FROM orders_products
  WHERE products_id = 85094
)
AND products_id != 85094
GROUP BY products_id
ORDER BY counter DESC
LIMIT 4

此查询需要很长时间,大约 20 秒。否则数据库不是很忙,并且在其他查询上表现良好。

我在想,是什么原因导致查询这么慢?

表相当大(大约 150 万行,大小大约 210 mb),这可能是内存问题吗?

有没有办法准确判断 mySQL 花了这么长时间?

解释的输出:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY     orders_products     range   products_id     products_id     4   NULL    1577863     Using where; Using temporary; Using filesort
2   DEPENDENT SUBQUERY  orders_products     ref     orders_id,products_id   products_id     4   const   2   Using where; Using temporary

【问题讨论】:

EXPLAIN?你能发布解释输出吗? 你有关于 orders_id 和 products_id 的索引吗? 提供表结构、索引和查询目的或预期输出。 orders_id 和 products_id 都有索引。添加了对问题的解释输出。 啊,我的老朋友“使用文件排序”。尝试删除ORDER 看看是否有帮助,至少作为隔离问题的一种方式。 【参考方案1】:

使用WHERE ID IN (subquery) 的查询在 mysql 中的表现非常糟糕。

然而,对于大多数此类查询,可以将它们重写为JOIN,这个也不例外:

SELECT
    t2.products_id,
    count(t2.products_id) AS counter
FROM orders_products t1
JOIN orders_products t2
    ON t2.orders_id = t1.orders_id
    AND t2.products_id != 85094 
WHERE t1.products_id = 85094
GROUP BY t2.products_id
ORDER BY counter DESC
LIMIT 4

如果您想返回没有 其他产品的行(并显示它们的计数为零),请将连接更改为LEFT JOIN

注意表的第一个实例有WHERE products_id = X,它允许索引查找并立即减少行数,而表的第二个实例有目标数据,但它在id字段上查找(再次快速),但在连接条件中过滤以计算 其他 产品。

【讨论】:

就像一个魅力,现在查询几乎不需要时间。 不用担心。顺便说一句,您对 group byorder by 的编辑是不必要的 - 无论哪种方式都可以正确执行:SQL 标准提供对列 position 的引用(而不是列 expression) 用于这些子句。 我同意 WHERE ID IN (subquery) 的性能在几乎所有 MySQL 数据库中都是出了名的差。 @ypercube WHERE IN () 哪些数据库在 IYHO 中表现良好? @ypercube 适当编辑,不使用 mysql 刷 tar 其他数据库【参考方案2】:

试试这些:

    MySQL 不使用子查询优化 IN - 将表连接在一起。 您的查询包含!= 条件,这很难处理 - 您能否缩小产品范围并使用多个查找而不是不公平比较?

【讨论】:

以上是关于为啥这个 mySQL 查询非常慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个查询运行这么慢?

mySql为啥查询时有时快,有时慢

MySQL 查询调优 - 为啥使用变量中的值比使用文字慢得多?

mysql为啥千万级别查询比1000条数据的查询慢

如何优化这个非常慢的 MySQL 查询?

为啥索引会使查询变得非常慢?