Порядок операций SQL - PullRequest
10 голосов
/ 19 мая 2009

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

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

Оценивается ли оператор WHERE до или после JOIN?

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

Ответы [ 7 ]

9 голосов
/ 19 мая 2009

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

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

7 голосов
/ 19 мая 2009

Ваша идея «оценки» неверна, поскольку SQL является декларативным языком.

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

6 голосов
/ 19 мая 2009

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

Как у вас уже есть, "только строки в" А из вчерашнего дня "соединяются с В".

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

Возвращает только A.date = "Yesterday" и присоединяется к B, где может найти совпадение на foo:

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

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

SELECT * FROM A
LEFT JOIN B
    ON A.foo=B.foo
    AND A.date="Yesterday"
2 голосов
/ 19 мая 2009

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

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

Оптимизация запросов - довольно богатая тема. В документации по любой используемой вами базе данных будет еще много информации об этом.

1 голос
/ 19 мая 2009

в SQL Server:

Как правило, предложения JOIN оцениваются перед предложениями 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
1 голос
/ 19 мая 2009

Зависит от индексов и статистики.

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

0 голосов
/ 23 августа 2010
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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...