这个MySQL查询(带子查询)可以优化吗?

时间:2010-03-04 19:22:37

标签: mysql optimization subquery

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

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 

3 个答案:

答案 0 :(得分:3)

我想你想在这里自我加入。将表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

答案 1 :(得分:1)

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` 

答案 2 :(得分:0)

是的,使用连接。大多数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