ORDER BY使MySQL查询变得极其缓慢

3
我有以下查询:
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;

省略ORDER BY部分运行查询,查询时间约为90毫秒;加上ORDER BY部分后,查询需要约8秒。

我在SO上浏览了一下,发现原因可能是在返回所有数据之前就执行了排序,而我们应该在结果集上运行ORDER BY?(参见此帖子:使用ORDER BY时查询缓慢

但我还无法确定如何明确地执行此操作?

3个回答

1
我在SO上浏览了一下,发现这个问题的原因可能是在返回所有数据之前执行了排序,而我们应该在结果集上运行ORDER BY,而不是在返回所有数据之前执行排序?我觉得很难相信,但如果确实是这个问题,我认为你需要像这样做。(请注意我放括号的位置。)
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;

此外,请编辑您的问题并包含该建议的链接。我认为我们中的许多人会从阅读它中受益。

其他可能无关的问题

在 WHERE 子句中使用的每个列都应该以某种方式进行索引。对于这个特定的查询,多列索引可能会表现得更好。

列 products.categories 似乎存储了您使用正则表达式过滤的多个值。在单个列中存储多个值通常是一个不好的想法。

MySQL 的 GROUP BY 是不确定的。使用标准 SQL 语句的 GROUP BY 可能会返回较少的行,并且可能会更快地返回它们。


问题编辑以包括链接。但是,您的答案会导致错误:“每个派生表都必须有自己的别名”——我想这意味着我们需要在右括号闭合之后(在“ORDER BY”之前)添加“AS something”,但是然后我得到“重复的列名' id '”——我想这是由于每个表都有一个'id'字段,但我不知道如何解决? - Christian Owens
1
那个链接指向你自己的问题,而不是那个说MySQL在返回所有数据之前开始排序的问题。你关于派生表别名位置的观点是正确的。看起来只有“products”表有一个名为“id”的列。使用实际的列名而不是SELECT *,修复应该很明显。如果失败了,请编辑您的问题并发布该查询中所有表的SQL DDL。 - Mike Sherrill 'Cat Recall'
抱歉,剪贴板出了问题。已经重新编辑并附上正确的链接。会尝试您的建议。 - Christian Owens
我不相信这样做会解决问题,但我很确定你所说的“在整个结果集上运行ORDER BY”是指这个。 - Mike Sherrill 'Cat Recall'

0

0
如果可以的话,您可能希望对ID列进行索引,以便查询运行更快。这是一个DBA级别的解决方案,而不是SQL解决方案 - 调整数据库将有助于提高整体性能。

所有的ID列都被索引了。 - Christian Owens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接