【问题标题】:Can this this MySQL query (with subqueries) be optimized?这个 MySQL 查询(带有子查询)可以优化吗?
【发布时间】:2010-03-04 19:22:37
【问题描述】:

有没有更好的方法来使这个查询工作?如果有可用的解决方案,我正在寻找更有效的解决方案。

SELECT `unitid`, `name` FROM apartmentunits WHERE aptid IN (
    SELECT `aptid` FROM rentconditionsmap WHERE rentcondid = 4 AND condnum = 1
) AND aptid IN (
    SELECT `aptid` FROM rentconditionsmap WHERE rentcondid = 2 AND condnum = 1
) ORDER BY name ASC 

【问题讨论】:

    标签: mysql optimization subquery


    【解决方案1】:

    我想你想在这里自我加入。将表rentconditionsmap 连接到自身,并指明连接两侧的条件。然后将该查询的结果加入apartmentunits

    (注意:尚未对此进行测试,可能需要一些调整...)

    SELECT `unitid`, `name` FROM `apartmentunits` 
     WHERE `unitid` IN (
            SELECT `unitid` FROM `rentconditionsmap` r1, `rentconditionsmap` r2
             WHERE r1.`unitid` = r2.`unitid`
               AND r1.`rentcondid` = 4
               AND r1.`condnum` = 1
               AND r2.`rentcondid` = 2
               AND r2.`condnum` = 1)
     ORDER BY `name` ASC
    

    【讨论】:

    • @tenner:您的查询有效。现在,如果我需要添加额外的rentcondid 和condnum 集,我是否只想在该查询中进行更多连接? SELECT unitid, name FROM apartmentunits WHERE aptid IN (SELECT r1.aptid FROMrentconditionsmap r1 JOIN rentconditionsmap r2 ON r1.aptid = r2.aptid WHERE r1.rentcondid = 4 AND r1.condnum = 1 AND r2.rentcondid = 2 AND r2.condnum = 1)
    • 是的,如果您有三个条件,那么您的自联接中需要三个表。
    【解决方案2】:
    SELECT a.`unitid`, 
           a.`name` 
    FROM   apartmentunits a 
           INNER JOIN rentconditionsmap r 
           ON a.aptid = r.aptid
       AND
           r.rentcondid in (2,4)
       AND 
           r.condnum = 1
    ORDER BY a.`name` 
    

    【讨论】:

      【解决方案3】:

      是的,使用连接。大多数 DBMS 将优化连接,使其不需要提取不需要的行。 MySQL 仍然使用嵌套循环,但我相信 Oracle 会使用哈希连接。

      所以这个查询最好表达为

      Select `unitid`, `name` FROM apartmentunits au
      INNER JOIN rentconditionsmap rcm1
      USING (aptid)
      INNER JOIN rentconditionsmap rcm2
      USING (aptid)
      WHERE rcm1.rentcondid = 4
      AND rcm1.condnum = 1
      AND rcm2.rendcondid = 2
      AND rcm2.condnum = 1
      

      【讨论】:

      • 更简单的说,不管DBMS如何,join order都会被优化,最好先从apartmentunits表中根据统计数据去FETCH,然后用它的数据来选出rentconditionsmap上的数据。在您的查询中,您基本上已经指定了连接顺序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      • 2022-10-30
      • 2011-04-25
      相关资源
      最近更新 更多