对包含带有group_concat的子查询的查询进行排序非常慢

时间:2014-01-04 10:23:01

标签: mysql

这是我的疑问:

SELECT 
  content.*, 
  mpt.asiakas.*, 
  (
    SELECT GROUP_CONCAT(t20.asryhma) FROM context t20 
    WHERE t20.asryhma <> 0 AND t20.asiakas = content.content_id) 
  AS asryhma 
FROM content JOIN mpt.asiakas ON content.resource_id = mpt.asiakas.as_id  
WHERE content.content_type_id = 27 
ORDER BY mpt.asiakas.as_k2 DESC, mpt.asiakas.as_os DESC, mpt.asiakas.as_vat ASC LIMIT 0,10

content是一个内容表(~20k行),其中包含所有者信息,时间戳和许多其他表的常用内容。 mpt.asiakas是实际内容数据的位置(~14k行),因此这两者首先连接在一起。这种设计应该减少冗余。 context是 - 缺少更好的术语 - 连接分配表(~3k行)。它就像一个补丁湾。

现在,如果我注释掉订购部分或子查询,查询大约需要0.01秒才能执行。但如果两者都存在,则查询执行大约需要17秒,这太过分了。我想知道可以做些什么呢?

1 个答案:

答案 0 :(得分:0)

尝试以这种方式重写此查询以限制执行GROUP_CONCAT的行:

SELECT t.*,
       (
           SELECT GROUP_CONCAT(t20.asryhma) FROM context t20 
           WHERE t20.asryhma <> 0 AND t20.asiakas = t.content_id
       ) AS asryhma 
FROM (
    SELECT 
      content.*, 
      mpt.asiakas.*
    FROM content 
    JOIN mpt.asiakas ON content.resource_id = mpt.asiakas.as_id  
    WHERE content.content_type_id = 27 
    ORDER BY mpt.asiakas.as_k2 DESC, 
             mpt.asiakas.as_os DESC, 
             mpt.asiakas.as_vat ASC 
    LIMIT 0,10
) AS t

使用索引优化ORDER BY子句是不可能的,因为现在的MySql优化器(版本5.7及更低版本)无法使用混合顺序ASC / DESC优化查询。

有关详情,请参阅此链接:
http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

  

在某些情况下,MySQL无法使用索引来解析ORDER BY,尽管它仍然使用索引来查找与WHERE子句匹配的行。
这些案件包括以下内容:
     .....
     .....
    - 你混合ASC和DESC:
  
  SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;