2009-05-18 3 views
9

Если я запускаю следующий SQL запросSQL порядок операций

SELECT * 
FROM A 
LEFT JOIN B 
ON A.foo=B.foo 
WHERE A.date = "Yesterday" 

ли WHERE заявление получить оценку до или после того, как в JOIN?

Если после того, что было бы лучшим способом написать этот оператор, чтобы только строки в A от "Yesterday" были соединены с B?

+0

', что было бы лучше, чтобы написать это заявление так, что только те строки, в A от «Вчера» присоединяются к Б.' (поздний ответ) -> 'INNER JOIN' –

ответ

8

Это зависит от базы данных.

На SQL Server запустите: SET SHOWPLAN_ALL ON, затем запустите запрос, вы получите представление о том, что произойдет, когда оно запустится.

1

В зависимости от индексов и статистики.

Вы должны указать путь выполнения запроса, чтобы определить, где (если есть) оптимизация должна применяться.

5

Семантически: после СОЕДИНЕНИЯ. Но в этом случае разница в времени отсутствует, потому что она находится на стороне LEFT JOIN.

Как у вас уже есть, «только строки из A с« Вчера »соединены с B».

Оптимизатор может свободно реорганизовывать свой порядок операций в зависимости от эквивалентности в реляционной алгебре.

Это возвращает только A.date = «Вчера» и присоединяется к B, где он может найти матч на обув:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
WHERE A.date="Yesterday" 

Это возвращает всех А, независимо от каких-либо критериев, и присоединяется к B, где A.date =» Вчера "И он находит совпадение по foo:

SELECT * FROM A 
LEFT JOIN B 
    ON A.foo=B.foo 
    AND A.date="Yesterday" 
+0

Просто чтобы понять, вы говорите, что включение критериев в предложение WHERE лучше с точки зрения производительности, чем помещение его в предложение JOIN? – NotMe

+0

Это не имеет никакого значения для производительности в INNER JOIN, поэтому оптимизатор имеет больше возможностей для перемещения вещей в INNER JOINs. В ВЗАИМОДЕЙСТВИИ (ВЛЕВО или ВПРАВО) это влияет на семантику декларации, поэтому производительность обычно не является проблемой. –

7

Ваша идея" оценки "неверна, так как SQL - это декларативный язык.

BTW вы можете увидеть план выполнения запроса. В MySQL префикс вашего запроса с ключевым словом describe, чтобы увидеть план выполнения.

2

Порядок операций для удовлетворения запроса определяется, почему прихоть оптимизатора запросов конкретной базы данных. Оптимизатор запросов пытается создать хороший «план запросов» (набор операций) на основе того, что он может извлечь из запроса и любой статистики, имеющейся у него в базе данных (которая может включать в себя мощность таблиц и некоторых распределений данных) ,

В вашем случае ответ может зависеть от того, есть ли у вас вторичный индекс A.date

оптимизации запросов довольно богатая тема. Документация для любой базы данных, которую вы используете, будет иметь гораздо больше, чтобы сказать об этом.

1

в SQL Server:

Как общее правило, ПРИСОЕДИНЯЙСЯ положения вычисляются до WHERE положений.

В случае сложных объединений, которые нуждаются фильтры в соединении части, я пишу их вместе с моим присоединиться

SELECT * 
FROM A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
    And A.Date = 'Yesterday' 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3 
+0

Это не имеет то же значение, когда вы используете его внутри LEFT JOIN. В LEFT JOIN, когда критерии не выполняются, строки LEFT все еще возвращаются, а любые столбцы из RIGHT - NULL. –

+0

Я стою исправлено на примере. Я пытался сделать так, чтобы поставить часть предложения вместе с соответствующим соединением. Я исправил это заявление. –

+0

:) Я стоял перекорректированный .. Я НЕ могу исправить утверждение. –

0
SELECT * 
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A 
LEFT JOIN B 
    ON A.Foo1 = B.Foo1 
OUTER JOIN C 
    ON B.Foo2 = C.Foo2 
JOIN D 
    ON B.Foo3 = D.Foo3 
Смежные вопросы