MySQL - IN(...)优化问题中的“选择”查询(=>分层查询)

Posted

技术标签:

【中文标题】MySQL - IN(...)优化问题中的“选择”查询(=>分层查询)【英文标题】:MySQL - "select" query inside IN (...) optimization issue (=> Hierarquical query ) 【发布时间】:2015-01-14 11:48:28 【问题描述】:

在您开始投票并拒绝我回答之前,请注意我是一个完整的初学者:)。我已经搜索了答案,但它似乎非常具体。

(作为一个程序员,我是怎么理解的,如果 select 语句 where for 循环,它就像一个循环里面一个循环里面一个循环:D)

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

SQL 分解:

第一次。查询

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

这个查询得到一个列表(准确地说是第二个查询中的列表),我想更上一层楼。 IE。再次在查询的 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)。然后我继续输入第二个查询。多合一查询试图将这两者合并为一个,即更深入 检查已批准答案的 cmets,结果发现我正在寻找的是所谓的分层查询。

【问题讨论】:

【参考方案1】:

试试

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

您的查询正在获取您的表 3 次,这就是它需要这么长时间的原因。其中之一是完全没有必要的,你只是在重复代码。

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

正如在 cmets 上讨论的那样,您正在寻找 分层查询,因为 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

【讨论】:

确实我是但是,它获取的数据不同,您的建议带来了第一个列表,所以它与我的第一个查询相同。我猜它是存储数据的方式。它有一个父母有一个祖父母,有一个祖父母,我想要祖父母名单:D 第一次和第二次查询没有区别。只有第二个您只获取一个字段submenu_id,可以在我的查询中轻松添加。除非你在你的问题上混合表格的名称是一样的。 嗯,也许我的问题并不清楚,我会编辑它,你让我知道它更清楚:) 现在我明白了。您正在寻找分层查询。编辑您的问题以明确这一点,并添加表的示例数据,仅包含重要的列和您想要的结果。 hm 真的很难写,因为没有桌子东西=[可能需要一段时间,或者如果你愿意,我可以添加截图

以上是关于MySQL - IN(...)优化问题中的“选择”查询(=>分层查询)的主要内容,如果未能解决你的问题,请参考以下文章

如何优化 MySQL 中的 IN 子查询?

使用“NOT IN”优化 MySQL 查询

Mysql优化

Mysql语句优化

Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

MySql in子句 效率低下优化(亲测有效,从200秒变1秒)