Чи оптимізовано приєднання до пункту де під час виконання?


14

Коли я пишу такий запит ...

select *
from table1 t1
join table2 t2
on t1.id = t2.id

Чи оптимізатор SQL, не впевнений, що це правильний термін, переводить це на ...

select *
from table1 t1, table2 t2
where t1.id = t2.id

По суті, чи є оператор Join в SQL Server просто простішим способом написання sql? Або він фактично використовується під час виконання?

Редагувати: я майже завжди і майже завжди буду використовувати синтаксис Join. Мені просто цікаво, що трапляється.


1
Не могли б ви детальніше зупинитися на "майже"? Коли б ви використовували синтаксис старого стилю і чому?
Аарон Бертран

2
Один крайний випадок, коли він має значення - це якщо ви додасте (застаріле) GROUP BY ALLв
Мартін Сміт,

@MartinSmith хтось використовує GROUP BY ALLспеціально? :-)
Аарон Бертран

@AaronBertrand - я сумніваюся в цьому! Не думаю, що я ніколи не бачив, щоб хтось цим користувався.
Мартін Сміт

Відповіді:


20

Вони руйнуються на одне і те ж всередині. Перший - це той, про який слід завжди писати . Що ще важливіше, чому це важливо? Вони однакові за планом виконання та продуктивності (якщо припустити, що ви не зіпсуєте це, що легше зробити із ледачим, синтаксисом старого стилю).

Ось доказ використання AdventureWorks про те, що такого немає CROSS JOINі filterтриває.


Явне приєднання:

введіть тут опис зображення


Неявне приєднання:

введіть тут опис зображення


Дивись, мамо! Ідентичні плани, однакові результати, відсутність перехресних з’єднань і фільтрів, які не зустрічаються ніде.

(Для наочності попередження для SELECTоператора в обох випадках - це неявна конвертація, що впливає на кардинальність, нічого спільного з об'єднанням в будь-якому випадку.)


20

Строго кажучи, є різниця у вході в оптимізатор запитів між двома формами:

-- Input tree (ISO-89)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM 
    Production.Product AS p,
    Production.ProductInventory AS inv
WHERE
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

Дерево вводу ISO-89

-- Input tree (ISO-92)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM Production.Product AS p
JOIN Production.ProductInventory AS inv ON
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

Дерево введення ISO-92

Як бачимо, ONприсудок припущення щільно прив’язаний до з'єднання за допомогою сучасного синтаксису. У старшому синтаксисі є логічне перехресне з'єднання з подальшим реляційним вибором (фільтр рядків).

Оптимізатор запитів майже завжди згортає реляційний вибір в об'єднанні під час оптимізації, тобто дві форми дуже ймовірно створюють еквівалентні плани запитів, але фактичної гарантії немає.


4

Для внутрішнього з'єднання вони взаємозамінні, але для зовнішніх з'єднань вони мають різний зміст - значення ON відповідає, і де просто проходить фільтрацію. Тож краще дотримуватися правильної відповідності синтаксису JOIN на УВІМКНЕНО.


4

Добре, мені було цікаво, тому я зробив тест. Я отримав фактичні плани виконання для наступного.

select * 
from sys.database_principals prin, sys.database_permissions perm
WHERE prin.principal_id = perm.grantee_principal_id

і

select * 
from sys.database_principals prin
JOIN sys.database_permissions perm
    ON prin.principal_id = perm.grantee_principal_id

Я порівнював їх предмет за об'єктом, і вони були однакові. Так хоча б для дуже простого прикладу вони вийшли на одне і те ж. Я також перевіряв статистику IO та час, і вони були досить близькими, щоб бути одне і те ж.

Незважаючи на це, ви повинні використовувати JOINсинтаксис, оскільки його легше читати, і ви рідше помиляєтесь, особливо у складних запитах. І *=/ =*синтаксис OUTERприєднується вже видалений в SQL-Server 2005.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.