Если вы посмотрите на 2 плана выполнения, есть ли простой ответ, который лучше? Я специально не создавал индексы, чтобы было легче увидеть, что происходит.
Второй план имеет более низкую оценочную стоимость, поэтому в этом ограниченном смысле он «лучше».
Наборы данных настолько малы, что оптимизатор не тратит много времени на поиск альтернатив. Первая форма запроса - это поиск плана с использованием хеш-соединения и буферизации таблицы. Ориентировочная стоимость этого плана настолько низка, что оптимизатору не нужно искать ничего лучшего.
Вторая форма запроса - это поиск плана с использованием только внешних вложений вложенных циклов в начале процесса поиска, и оптимизатор снова решает, что план достаточно хорош. Так получилось, что этот план оценивается дешевле.
При этом (как уже упоминалось в комментариях к вопросу) эти два запроса не являются семантически идентичными. Это может быть не важно для вас, если вы можете гарантировать, что результаты всегда будут одинаковыми для всех возможных будущих состояний вашей базы данных, но оптимизатор не может сделать такое предположение. Он только когда-либо создает планы, которые гарантированно дают одинаковые результаты, указанные SQL, при любых обстоятельствах.
Я понял, что вложенный синтаксис также изменяет поведение запроса.
«Вложенный синтаксис» является лишь одним аспектом всей спецификации синтаксиса соединения ANSI. Чтобы включить полную логическую спецификацию для более сложных шаблонов соединения, спецификация допускает (необязательные) круглые скобки и FROM
подзапросы предложений.
Запрос может быть написан с использованием того же синтаксиса ANSI с использованием скобок:
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN
(
dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) ON M.ModelID = A.ModelID;
Эта форма ясно показывает , что логическое требование заключается в левое соединение с Autos
в результате внутрипартийных присоединения Manufacturers
к Models
. Пропуск необязательных скобок дает форму, которую вы называете «вложенной»:
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
ON M.ModelID = A.ModelID;
Это не другой синтаксис - он просто пропускает необязательные скобки и немного переформатирует.
Как упоминал Мартин, в этом случае также возможно выразить логическое требование, используя внутренние объединения, за которыми следует правое внешнее соединение:
SELECT
A.*,
M.*,
N.*
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
RIGHT JOIN dbo.Autos AS A
ON A.ModelID = M.ModelID;
Все три формы запроса, приведенные выше, используют один и тот же синтаксис соединения ANSI. Все три также создают один и тот же физический план выполнения с предоставленным набором данных:
Как я уже упоминал в своем ответе на предыдущий вопрос, запросы, которые выражают одно и то же логическое требование, не всегда приводят к одному и тому же плану выполнения. Какую форму логического запроса вы предпочитаете использовать, во многом зависит от стиля. Нет никакой корреляции между одним конкретным стилем и «лучшими» планами запросов в целом. Я бы вообще не советовал переписывать запрос, чтобы получить конкретный план, если новый запрос не является действительно логически идентичным оригиналу.
Стандарт SQL также допускает FROM
подзапросы предложений, поэтому еще один способ написать ту же спецификацию запроса:
SELECT *
FROM dbo.Autos AS A
LEFT JOIN
(
SELECT
N.ManufacturerID,
ManufacturerName = N.Name,
M.ModelID,
ModelName = M.Name
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) AS R1
ON R1.ModelID = A.ModelID;
Используя традиционный синтаксис, мы должны изменить соединение на «Производители» на внешнее объединение, например, так ... но это меняет план запроса.
Это , вероятно , изменяет значение запроса, в этом случае это технически не является действительной альтернативой (но см ypercube «s комментарий на ваш вопрос).
(Необязательные) круглые скобки в синтаксисе соединения ANSI предназначены именно для таких более сложных требований к соединению, как этот, поэтому вы не должны бояться использовать их при необходимости.