繁体   English   中英

Mysql GROUP BY子查询花费太多时间

[英]Mysql GROUP BY subqueries takes too much time

我有大量使用三个子查询的查询。

SELECT m.id AS id,
       m.restaurant_id,
       m.title_en AS title,
       m.description_en AS description,
       CONCAT('{"id":',m.id, ', "title": "',m.title_en, '", "description": "', m.description_en, '", "categories": ', '[',GROUP_CONCAT('{"id":',f.id,',"name": "',f.name_en,'"',',"description": "',f.description_en,'"',',"items": ',f.items,'}' SEPARATOR ','),']','}') categories
FROM menus m
INNER JOIN
  (SELECT c.id AS id,
          c.name_en AS name_en,
          c.menu_id AS menu_id,
          c.description_en AS description_en,
          CONCAT('[',GROUP_CONCAT('{"id":',g.id,',"name": "',g.name_en,'"',',"description": "',g.description_en,'"',',"sizes": ',g.sizes,'}' SEPARATOR ','),']') items
   FROM categories c
   INNER JOIN
     (SELECT i.id AS id,
             i.name_en AS name_en,
             i.category_id AS category_id,
             i.description_en AS description_en,
             CONCAT('[',GROUP_CONCAT('{"name": "',s.name_en,'"',',"price":', si.price,'}' SEPARATOR ','),']') sizes
      FROM items i
      INNER JOIN items_sizes si ON si.item_id = i.id
      INNER JOIN sizes s ON si.size_id = s.id
      GROUP BY i.id) g ON g.category_id = c.id
   GROUP BY c.id) f ON m.id = f.menu_id
GROUP BY m.id
HAVING m.restaurant_id = 1 LIMIT 10;   

该查询导致类似

{id: "",
 title: "",
 desctiption: "",
 categories: {
               id: "",
               name: "",
               description: "",
               items: {
                   id: "",
                   name: "",
                   description: "",
                   sizes: { 
                           name: "",
                           price: ""
                   }
               }
          }
 } 

但是,此查询需要20秒钟才能运行,这是非常大的。 我怀疑其原因是子查询的大量使用,但是我不确定并且找不到其他方法来实现此复杂查询

编辑:有一个具有标题和描述的表格菜单,菜单具有许多类别,而类别又具有名称和描述。 一个类别有很多项目,而这些项目又有很多大小,我想要实现的是通过组concat将json字符串中的所有内容聚合在一起,并且我得到了正确的结果,问题是它花费的时间超过20秒对于我正在开发的当前应用程序来说是灾难性的。

菜单(id:整数,title_en:字符串,description_en:字符串);

类别(id:整数,name_en:字符串,description_en:描述,menu_id:整数)

items(id:整数,name_en:字符串,description:字符串,category_id:整数)

items_sizes(id:整数,price:整数,item_id:整数,size_id:整数)

大小(id:整数,name_en:字符串);

编辑:

结果的解释

1,PRIMARY,m,index,PRIMARY,PRIMARY,4,,4060,

1,PRIMARY,,ref,key0,key0,4,m.id,98,

2,派生,c,索引,PRIMARY,PRIMARY,4,,39961,

2,DERIVED,ref,key0,key0,5,c.id,10,

3,DER,s,ALL,PRIMARY,,,,,1122,使用临时 使用文件排序

3,DERIVED,si,ref,item_id,size_id,size_id,4,s.id,338,

3,派生,i,eq_ref,PRIMARY,PRIMARY,4,si.item_id,1,

在这种情况下,子查询是一个巨大的缺点。 如果您的sql查询中有多个子查询,则查询输出的时间将随着子查询数量的增加而呈指数增长。

简而言之,子查询将为每个父行重复执行。 假设父表中有50行,那么子查询将执行50次。

看一下该链接,它描述了子查询中的问题。

http://dev.mysql.com/doc/mysql-reslimits-excerpt/5.6/en/subquery-restrictions.html

如果内部查询和外部查询分别返回M和N行,则执行时间将变成O(M×N)的顺序,而不是像不相关子查询那样的O(M + N)。

暂无
暂无

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

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