TSQL - Каков правильный порядок объединения таблиц? - PullRequest
12 голосов
/ 29 марта 2012

Мой гугл-фу и со-фу меня здесь подводят, так что я могу спросить.

У меня много запросов с несколькими объединениями.

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

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

Это правильно?

Лучше ли присоединяться к большим таблицам перед поиском таблиц? Или наоборот?

Должен ли я использовать подсказку loop при соединении с небольшими таблицами и подсказку merge при объединении с открытыми наборами?

Я уверен, что ответ «это зависит», но некоторые общие рекомендации по эффективному и результативному объединению были бы очень полезны. Спасибо!

Ответы [ 2 ]

12 голосов
/ 29 марта 2012

РЕДАКТИРОВАТЬ: Исходя из ваших комментариев (и комментария Кирка Волля), вы должны понимать, что порядок ваших объединений эстетичен и не оказывает прямого влияния на итоговый план выполнения .Оптимизатор запросов выполнит объединения в наиболее эффективном порядке и большую часть времени будет использовать соответствующую операцию соединения без каких-либо подсказок.

Когда дело касается эстетики вашего порядка соединения, это немногосубъективно, но я бы сказал, что объединение ваших таблиц в любом порядке имеет логический смысл при чтении запроса ... если вы начинаете с @HeaderId, начинайте с этой таблицы, а затем JOIN с дочерних таблиц:

FROM
    Header h
    JOIN Items i ON h.HeaderId = i.HeaderId
    JOIN Details d ON i.ItemId = d.ItemId
WHERE
    h.HeaderId = @HeaderId

Но, если бы вы начали свой запрос с @DetailId, я бы присоединился в обратном порядке.

FROM
    Details d
    JOIN Items i ON d.ItemId = i.ItemId
    JOIN Header h ON i.HeaderId = h.HeaderId
WHERE
    d.DetailId = @DetailId

Однако это субъективно и только мое личное предпочтение.

Это становится менее субъективным, когда вы начинаете включать OUTER JOIN s ... попробуйте структурировать свой запрос, чтобы избежать любых RIGHT OUTER JOIN s, и вместо этого используйте LEFT OUTER JOIN.

Не используйте joinподсказки по умолчанию ... фактически вы почти никогда не будете их использовать.Оптимизатор запросов отлично справляется с выбором оптимального плана выполнения.Я встречал только один случай, когда мне нужно было предоставить подсказку о присоединении для улучшения плана ... он сильно помог на сервере, на котором выполнялся запрос, но когда база данных была перенесена на другой сервер,Моя подсказка о присоединении уничтожила производительность запроса.Итак, повторюсь, обычно плохая идея предоставлять подсказки о присоединении.

0 голосов
/ 01 июня 2012

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

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

[1] Я знаю один случай, когда заказ имеет значение:

CREATE TABLE A (
  id int IDENTITY PRIMARY KEY,
  name varchar
);

CREATE TABLE B (
  id int IDENTITY PRIMARY KEY,
  a_id int FOREIGN KEY REFERENCES A (id),
  name varchar
);

SELECT *
FROM A
INNER LOOP JOIN B on A.id = B.a_id;

SELECT *
FROM B
INNER LOOP JOIN A on A.id = B.a_id;

Первый выбор выполняет два сканирования индекса, второй выполняет сканирование и поиск. Это еще одна веская причина избегать подсказок.

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