2010-03-04 1 views
0

Есть ли лучший способ заставить этот запрос работать? Я ищу более эффективное решение, если есть один доступный.Может ли этот запрос MySQL (с подзапросами) быть оптимизирован?

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

Я думаю, что вам нужна самоподготовка. Присоедините таблицу 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 
+0

@tenner: Ваш запрос работает. Теперь, хотел бы я просто начать с большего количества объединений внутри этого запроса, если мне нужно было добавить дополнительные наборы rentcondid и condnum? SELECT unitid, имя FROM квартиры, где есть aptid IN (SELECT r1.aptid FROM rentconditionsmap 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) –

+0

Да, если у вас есть три условия, вам понадобится три таблицы в вашем объединении. – Tenner

0

Да, с помощью соединения. Большинство СУБД оптимизируют соединение таким образом, что ему не нужно вытягивать строки, которые ему не нужны. 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 
+0

Проще говоря, порядок соединения будет оптимизирован независимо от СУБД, и он может быть лучше основан на статистике FETCH из таблицы квартир, а затем использовать ее данные для выбора данных об арендеconditionsmap. В вашем запросе вы существенно продиктовали порядок соединения. –

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` 

 Смежные вопросы

  • Нет связанных вопросов^_^