MySQL - "选择" IN(...)优化问题内的查询(=>层次查询)

时间:2015-01-14 11:48:29

标签: mysql sql-optimization

在开始投票并拒绝给我答案之前,请注意我是一个完全的初学者:)。我已经找到了答案,但似乎非常具体。

(我如何理解它作为程序员,如果select语句for循环,它就像循环中循环内的循环:D)

问题是关于优化我的sql查询,因为它需要几秒钟才能获取数据。

SQL细分:

第一次查询

SELECT * 
FROM r_submenuitems 
WHERE modifier1 IN (SELECT submenu_id FROM r_submenuitems WHERE item_id = 1068)

这个查询得到一个列表(确切地说是第二个查询中的列表),我想要更高一步。即再次在查询的IN子句中使用此列表并获取新列表。

第二。查询

SELECT submenu_id 
FROM r_submenuitems 
WHERE modifier1 IN (31050, 131050,3912, 103122, 103165, 7772, 7782)

要将2个查询合并为1,我执行了以下操作:

SELECT submenu_id FROM r_submenuitems 
WHERE modifier1 IN (SELECT submenu_id FROM r_submenuitems 
    WHERE modifier1 IN (SELECT submenu_id FROM r_submenuitems 
        WHERE item_id = 1068))

获取数据需要很长时间。

是否有更好的(更快获取)方式合并上面的两个查询? 如果没有,是第一个解决方案,即比拥有一体化查询更好的2个查询?

编辑:第一个查询返回条目列表(31050,131050,3912,103122,103165,7772,7782)。然后我继续提供第二个查询。一体化查询尝试将这两者合并为一个,即更深入 查看已批准答案的评论,结果我正在寻找的是Hierarquical查询。

1 个答案:

答案 0 :(得分:3)

尝试

SELECT submenu_id  
  FROM r_submenuitems r1
           INNER JOIN r_submenuitems r2
             ON r1.modifier1 = r2.submenu_id
 WHERE r2.item_id = 1068

您的查询是三次获取您的表,这就是为什么它需要这么长时间。其中一个完全没必要,你只是重复代码。

SELECT submenu_id FROM r_submenuitems 
 WHERE modifier1 IN (SELECT submenu_id                   --All this IN statement is
                       FROM r_submenuitems               --unnecessary you are already
                      WHERE modifier1 IN ( SELECT submenu_id -- doing on the inner IN
                                             FROM r_submenuitems 
                                            WHERE item_id = 1068
                                         )
                    )

修改2

正如您在评论中所讨论的那样,您正在寻找 Hierarquical Query ,因为mysql不支持对本机命令的这种操作,您至少要知道自己想要的深度要创建一个查询以从该级别获取数据,您将看到它需要为每个级别添加JOIN操作。

替代方法是创建一个带有一些递归的存储过程(我不会解释这个)看看这里MANAGING HIERARCHICAL DATA IN MYSQL

您的问题的查询将是(对于第三级)

SELECT r1.submenu_id  
  FROM r_submenuitems r1 
        INNER JOIN r_submenuitems r2 ON r1.modifier1 = r2.submenu_id
        INNER JOIN r_submenuitems r3 ON r2.modifier1 = r3.submenu_id
 WHERE r3.item_id = 1068