[英]Why is this mySQL query extremely slow?
Given is a mySQL table named "orders_products" with the following relevant fields: 给定的是名为“orders_products”的mySQL表,其中包含以下相关字段:
Both fields are indexed. 这两个字段都已编入索引。
I am running the following query: 我正在运行以下查询:
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
This query takes extremely long, around 20 seconds. 此查询需要很长时间,大约20秒。 The database is not very busy otherwise, and performs well on other queries. 否则数据库不是很忙,并且在其他查询上表现良好。
I am wondering, what causes the query to be so slow? 我想知道,是什么导致查询这么慢?
The table is rather big (around 1,5 million rows, size around 210 mb), could this be a memory issue? 该表相当大(大约150万行,大小约为210 mb),这可能是一个内存问题吗?
Is there a way to tell exactly what is taking mySQL so long? 有没有办法确切地告诉我们SQLSQL需要这么长时间?
Output of Explain: 解释输出:
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
Queries that use WHERE ID IN (subquery)
perform notoriously badly with mysql. 使用WHERE ID IN (subquery)
与mysql的表现非常糟糕。
With most cases of such queries however, it is possible to rewrite them as a JOIN
, and this one is no exception: 但是,对于大多数此类查询的情况,可以将它们重写为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
If you want to return rows where there are no other products (and show a zero count for them), change the join to a LEFT JOIN
. 如果要返回没有其他产品的行(并显示零计数),请将连接更改为LEFT JOIN
。
Note how the first instance of the table has the WHERE products_id = X
, which allows index look up and immediately reduces the number of rows, and the second instance of the table has the target data, but it looked up on the id field (again fast), but filtered in the join condition to count the other products. 注意表的第一个实例如何具有WHERE products_id = X
,它允许索引查找并立即减少行数,表的第二个实例具有目标数据,但它在id字段上查找(再次快速),但在连接条件下过滤以计算其他产品。
Give these a try: 试一试:
!=
condition, which is very difficult to deal with - can you narrow down products and use multiple lookups rather than inequity comparison? 您的查询包含!=
条件,这很难处理 - 您是否可以缩小产品范围并使用多个查找而不是不公平比较?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.