По-перше, припустимо, що (id)
це основний ключ таблиці. У цьому випадку так, з'єднання є (можна довести) надмірними і їх можна усунути.
Тепер це просто теорія - або математика. Для того, щоб оптимізатор здійснив фактичне усунення, теорію необхідно було перетворити в код і додати до набору оптимізаторів оптимізацій / перезаписів / усунень. Щоб це сталося, розробники (СУБД) повинні думати, що це матиме хороші переваги для ефективності та що це досить поширений випадок.
Особисто це не звучить як одне (досить поширене). Запит - як ви визнаєте - виглядає досить нерозумно, і рецензент не повинен дозволяти йому пройти огляд, якщо тільки він не був покращений і не було видалено зайве приєднання.
Однак, є подібні запити, коли усунення відбувається. Є дуже приємна пов’язана публікація в блозі Роб Фарлі: ПРИЄДНАЙТЕ спрощення в SQL Server .
У нашому випадку все, що нам потрібно зробити, щоб змінити приєднання до LEFT
приєднань. Дивіться dbfiddle.uk . Оптимізатор в цьому випадку знає, що з'єднання можна безпечно зняти без можливих змін результатів. (Логіка спрощення є досить загальною і не має особливих причин для самостійного приєднання.)
Звичайно, в оригінальному запиті видалення INNER
з'єднань також не може змінити результати. Але взагалі не властиво самостійно приєднуватися до первинного ключа, тому оптимізатор не має цього випадку реалізований. Однак загальним є приєднання (або приєднання ліворуч), де стовпчик об'єднаних є основним ключем однієї з таблиць (а часто існує обмеження зовнішнього ключа). Що призводить до другого варіанта усунення приєднань: Додайте обмеження зовнішнього ключа (самонавірення!):
ALTER TABLE "Table"
ADD FOREIGN KEY (id) REFERENCES "Table" (id) ;
І вуаля, приєднання усуваються! (випробувано в тій же скрипці): ось
create table docs
(id int identity primary key,
doc varchar(64)
) ;
GO
✓
insert
into docs (doc)
values ('Enter one batch per field, don''t use ''GO''')
, ('Fields grow as you type')
, ('Use the [+] buttons to add more')
, ('See examples below for advanced usage')
;
GO
Зачеплені 4 ряди
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | док
-: | : ----------------------------------------
1 | Введіть одну партію в поле, не використовуйте "GO"
2 | Поля росте під час введення
3 | Використовуйте кнопки [+], щоб додати більше
4 | Див. Приклади для розширеного використання
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
left join docs d2 on d2.id=d1.id
left join docs d3 on d3.id=d1.id
left join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | док
-: | : ----------------------------------------
1 | Введіть одну партію в поле, не використовуйте "GO"
2 | Поля росте під час введення
3 | Використовуйте кнопки [+], щоб додати більше
4 | Див. Приклади для розширеного використання
alter table docs
add foreign key (id) references docs (id) ;
GO
✓
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | док
-: | : ----------------------------------------
1 | Введіть одну партію в поле, не використовуйте "GO"
2 | Поля росте під час введення
3 | Використовуйте кнопки [+], щоб додати більше
4 | Див. Приклади для розширеного використання