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

这个MySQL查询(带子查询)可以优化吗?,mysql,optimization,subquery,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 rentcon

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

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 

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

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

是的,使用连接。大多数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都会优化连接,这样它就不需要拉取不需要的行。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的情况下得到优化,并且最好基于统计信息首先从apartmentunits表中获取数据,然后使用其数据在rentconditionsmap上选择数据。在您的查询中,您基本上已经指定了连接顺序。更简单地说,连接顺序将在不考虑DBMS的情况下得到优化,并且最好基于统计信息,首先从apartmentunits表中获取数据,然后使用其数据在rentconditionsmap上选择数据。在您的查询中,您基本上已经指定了连接顺序。@tenner:您的查询有效。现在,如果我需要添加额外的rentcondid和condnum集,我是否只想在该查询中继续进行更多连接?选择unitid,name FROM apartmentunits WHERE ApId IN SELECT r1.ApId FROM rentconditionsmap r1 JOIN rentconditionsmap r2 ON r1.ApId=r2.ApId其中r1.rentcondid=4和r1.condnum=1和r2.rentcondid=2和r2.condnum=1是的,如果您有三个条件,您的自联接中需要三个表。@tenner:您的查询有效。现在,如果我需要添加额外的rentcondid和condnum集,我是否只想在该查询中继续进行更多连接?选择unitid,name FROM apartmentunits WHERE apId IN SELECT r1.apId FROM rentconditionsmap r1 JOIN rentconditionsmap r2 ON r1.apId其中r1.rentcondid=4和r1.condnum=1和r2.rentcondid=2和r2.condnum=1是的,如果有三个条件,则需要在自联接中使用三个表。