简体   繁体   中英

Ordering a query that contains a subquery with a group_concat is very slow

This is my query:

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 is a content table (~20k rows) which contains owner information, timestamps and the usual for many other tables. mpt.asiakas is where the actual content data is (~14k rows), so these two are first joined together. This design is supposed to reduce redundacy. context is a - for lack of a better term - join assignment table (~3k rows). It works like a patch bay.

Now, if I comment out either the ordering part or the subquery, the query takes about 0.01 seconds to execute. But if both are present the query takes about 17 seconds to execute, which is way too much. I wonder what can be done about this?

Try to rewrite this query in this way to limit rows on which GROUP_CONCAT is performed:

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

Optimization of ORDER BY clause using indexes is not possible, because the MySql optimizer for now (version 5.7 and below) cannot optimize queries with mixed order ASC/DESC.

See this link for details:
http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

In some cases, MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause.
These cases include the following:
.....
.....
- You mix ASC and DESC:

SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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