SQL Server 2005 - порядок внутренних соединений - PullRequest
5 голосов
/ 26 августа 2009

У меня есть запрос, содержащий три внутренних оператора соединения в предложении Where. Выполнение запроса занимает около 2 минут. Если я просто изменю порядок двух внутренних соединений, производительность упадет до 40 секунд.

Как ничто, кроме изменения порядка внутренних объединений, может оказать столь сильное влияние на производительность запросов? Я бы подумал, что оптимизатор все это выяснит.

Ответы [ 3 ]

8 голосов
/ 26 августа 2009

SQL является декларативным, то есть порядок соединения не должен иметь значения.

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

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

И это также может быть способ указания предложения ON. Он должен измениться, если вы переупорядочите предложение FROM. Если вы не используете более старое (и плохое) предложение JOIN-in-the-WHERE.

Наконец, если это проблема, вы можете использовать скобки, чтобы изменить порядок оценки, чтобы прояснить свои намерения, скажем, сначала отфильтровать большую таблицу, чтобы создать производную таблицу.

4 голосов
/ 26 августа 2009

Поскольку, изменяя порядок соединений, SQL Server предлагает другой план выполнения для вашего запроса (скорее всего, он меняет способ фильтрации таблиц на основе ваших объединений).

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

В одном запросе ваши объединения объединяют несколько больших таблиц, а затем фильтруют записи в конце.

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

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

0 голосов
/ 26 августа 2009

Я бы подумал, что он достаточно умен, чтобы делать это, но очевидно, что он по-прежнему выполняет объединения в том порядке, в котором вы их явно перечислили ... Что касается того, почему это влияет на производительность, если первое соединение дает промежуточный результат набор только из 100 записей в одной схеме упорядочения, тогда второе соединение будет из этого набора из 100 записей в третью таблицу. Если при первом объединении другого соединения будет получен первый промежуточный набор результатов из одного миллиона записей, то второе соединение будет из набора результатов из одного миллиона строк в третью таблицу ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...