Mysql GROUP BY子查询占用太多时间

时间:2015-10-10 10:40:31

标签: mysql

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

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秒才能运行,这是非常巨大的。我怀疑原因是大量使用子查询但是我不确定并且找不到其他方法来实现这个复杂的查询

修改 有一个具有标题和描述的表格菜单,菜单有许多类别,而这些类别又具有名称和描述。一个类别有许多项目,而这些项目又有很多大小我想要实现的是json字符串中所有那些通过组连接聚合它的工作,我有正确的结果问题是它需要的时间超过20秒对于我正在开发的当前应用来说是灾难性的。

  

menus(id:integer,title_en:string,description_en:string);

     

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

     

items(id:integer,name_en:string,description:string,   CATEGORY_ID:整数)

     

items_sizes(id:整数,价格:整数,item_id:整数,   size_id:整数)

     

sizes(id:integer,name_en:string);

修改

EXPLAIN的结果

  

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

     

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

     

2,DERIVED,c,index,PRIMARY,PRIMARY,4,,39961,

     

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

     

3,DERIVED,s,ALL,PRIMARY ,,,, 1122,暂时使用;运用   文件排序

     

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

     

3,DERIVED,i,eq_ref,PRIMARY,PRIMARY,4,si.item_id,1,

1 个答案:

答案 0 :(得分:3)

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

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

看看这个描述子查询中的问题的链接。

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

  

如果内部和外部查询分别返回M行和N行,则执行时间变为O(M×N),而不是O(M + N),就像对于不相关的子查询一样。 / p>

相关问题