MySQL - "select"查询中IN (...)优化问题(=>分层查询)

4
在你开始给我点踩并否认我的回答之前,请注意我是一个完全的初学者:)。我已经搜索过答案了,但似乎它非常具体。
(作为程序员,我的理解是,如果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)

为了将这两个查询合并为一个,我执行了以下操作:
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),然后我继续将其提供给第二个查询。全合一查询试图将这两个查询合并成一个,即进一步深入。请查看已批准答案的评论,结果发现我正在寻找的被称为分层查询。
1个回答

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

如评论中所讨论的,您正在寻找一种分层查询,因为mysql不支持这种原生操作,所以您至少需要知道要多深才能创建一个查询,从那个级别获取数据,您会发现需要添加每个级别的JOIN操作。

替代方法是创建一个带有一些递归的存储过程(我不会解释),请看这里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

确实如此,但它获取的数据不同,您的建议带来了第一个列表,所以与我的第一个查询相同。我猜这是数据存储的方式所致,它有一个父项,其中又有一个祖先和曾祖父,而我想要曾祖父列表:D - hahaha
第一次查询和第二次查询没有区别。只是第二次查询你只获取一个字段 submenu_id,这可以很容易地添加到我的查询中。除非你在问题中混淆了表的名称,否则都是相同的。 - Jorge Campos
或许我在问题描述上不够明确,我会修改一下,请您再看看是否更清楚了 :) - hahaha
哎呀,因为没有表格的东西,所以很难写出来 =[ 可能需要一些时间,或者如果你愿意,我可以添加一张截图。 - hahaha
谢谢,非常完美 :)。我会编辑我的标题以包含分层查询。 - hahaha
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接