简体   繁体   English

ORDER BY导致MySQL查询变得非常慢

[英]ORDER BY Causes MySQL query to become Extremely Slow

I have the following query: 我有以下查询:

SELECT * 
FROM   products 
   INNER JOIN product_meta 
           ON products.id = product_meta.product_id 
   JOIN sales_rights 
     ON product_meta.product_id = sales_rights.product_id 
WHERE  ( products.categories REGEXP '[[:<:]]5[[:>:]]' ) 
   AND ( active = '1' ) 
   AND ( products.show_browse = 1 ) 
   AND ( product_meta.software_platform_mac IS NOT NULL ) 
   AND ( sales_rights.country_id = '240' 
          OR sales_rights.country_id = '223' ) 
GROUP  BY products.id 
ORDER  BY products.avg_rating DESC
LIMIT  0, 18;

Running the query with the omission of the ORDER BY section and the query runs in ~90ms, with the ORDER BY section and the query takes ~8s. 在省略ORDER BY部分的情况下运行查询并且查询在~90ms内运行,使用ORDER BY部分和查询需要~8s。

I've browsed around SO and have found the reason for this could be that the sort is being executed before all the data is returned, and instead we should be running ORDER BY on the result set instead? 我已经浏览了SO并且发现原因可能是在返回所有数据之前正在执行排序,而是我们应该在结果集上运行ORDER BY (See this post: Slow query when using ORDER BY ) (参见这篇文章: 使用ORDER BY时查询速度慢

But I can't quite figure out the definitive way on how I do this? 但我无法弄清楚我如何做到这一点的明确方式?

I've browsed around SO and have found the reason for this could be that the sort is being executed before all the data is returned, and instead we should be running ORDER BY on the result set instead? 我已经浏览了SO并且发现原因可能是在返回所有数据之前正在执行排序,而是我们应该在结果集上运行ORDER BY?

I find that hard to believe, but if that's indeed the issue, I think you'll need to do something like this. 我发现很难相信,但如果这确实是问题,我认为你需要做这样的事情。 (Note where I put the parens.) (注意我把它放在哪里。)

select * from
(
  SELECT products.id, products.avg_rating 
  FROM   products 
  INNER JOIN product_meta 
          ON products.id = product_meta.product_id 
  JOIN sales_rights 
    ON product_meta.product_id = sales_rights.product_id 
  WHERE  ( products.categories REGEXP '[[:<:]]5[[:>:]]' ) 
   AND ( active = '1' ) 
   AND ( products.show_browse = 1 ) 
   AND ( product_meta.software_platform_mac IS NOT NULL ) 
   AND ( sales_rights.country_id = '240' 
          OR sales_rights.country_id = '223' ) 
  GROUP  BY products.id 
) as X
ORDER  BY avg_rating DESC
LIMIT  0, 18;

Also, edit your question and include a link to that advice. 此外,编辑您的问题并包含该建议的链接。 I think many of us would benefit from reading it. 我想我们很多人都会从阅读中受益。


Additional, possibly unrelated issues 其他可能不相关的问题

Every column used in a WHERE clause should probably be indexed somehow. WHERE子句中使用的每个列都应该以某种方式编入索引。 Multi-column indexes might perform better for this particular query . 多列索引可能对此特定查询执行得更好。

The column products.categories seems to be storing multiple values that you filter with regular expressions. 列products.categories似乎存储了使用正则表达式过滤的多个值。 Storing multiple values in a single column is usually a bad idea. 在单个列中存储多个值通常是个坏主意。

MySQL's GROUP BY is indeterminate . MySQL的GROUP BY是不确定的 A standard SQL statement using a GROUP BY might return fewer rows, and it might return them faster. 使用GROUP BY标准SQL语句可能返回较少的行,并且可能更快地返回它们。

If you can, you may want to index your ID columns so that the query will run quicker. 如果可以,您可能希望索引ID列,以便查询更快地运行。 This is a DBA-level solution, rather than a SQL solution - tuning the database will help overall performance. 这是一个DBA级解决方案,而不是SQL解决方案 - 调整数据库将有助于整体性能。

The issue in the instance of this query, was that by using GROUP BY and ORDER BY in a query, MySQL is unable to use the index if the GROUP BY and ORDER BY expressions are different. 此查询实例中的问题是,通过在查询中使用GROUP BYORDER BY ,如果GROUP BYORDER BY表达式不同,MySQL无法使用索引。

Related Reading: 相关阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM