Tout d'abord, supposons que (id)
c'est la clé primaire de la table. Dans ce cas, oui, les jointures sont (peuvent être prouvées) redondantes et pourraient être éliminées.
Maintenant, c'est juste de la théorie - ou des mathématiques. Pour que l'optimiseur fasse une élimination réelle, la théorie doit avoir été convertie en code et ajoutée dans la suite d'optimisations / réécritures / éliminations de l'optimiseur. Pour que cela se produise, les développeurs (SGBD) doivent penser que cela aura de bons avantages en termes d'efficacité et que c'est un cas assez courant.
Personnellement, cela ne ressemble pas à un (assez commun). La requête - comme vous l'admettez - semble plutôt idiote et un réviseur ne devrait pas la laisser passer en revue, sauf si elle a été améliorée et la jointure redondante supprimée.
Cela dit, il existe des requêtes similaires où l'élimination se produit. Il y a un très bon article de blog connexe de Rob Farley: JOIN simplification dans SQL Server .
Dans notre cas, tout ce que nous avons à faire pour changer les jointures en LEFT
jointures. Voir dbfiddle.uk . L'optimiseur dans ce cas sait que la jointure peut être supprimée en toute sécurité sans modifier les résultats. (La logique de simplification est assez générale et n'a pas de cas particulier pour les auto-jointures.)
Dans la requête d'origine, bien sûr, la suppression des INNER
jointures ne peut pas non plus modifier les résultats. Mais il n'est pas du tout courant de s'auto-joindre sur la clé primaire, donc l'optimiseur n'a pas ce cas implémenté. Il est cependant courant de joindre (ou de joindre à gauche) où la colonne jointe est la clé primaire de l'une des tables (et il y a souvent une contrainte de clé étrangère). Ce qui conduit à une deuxième option pour éliminer les jointures: Ajoutez une contrainte de clé étrangère (auto-référencement!):
ALTER TABLE "Table"
ADD FOREIGN KEY (id) REFERENCES "Table" (id) ;
Et le tour est joué, les jointures sont éliminées! (testé dans le même violon): ici
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 lignes affectées
--------------------------------------------------------------------------------
-- 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 | doc
-: | : ----------------------------------------
1 | Entrez un lot par champ, n'utilisez pas 'GO'
2 | Les champs grandissent à mesure que vous tapez
3 | Utilisez les boutons [+] pour ajouter plus
4 | Voir les exemples ci-dessous pour une utilisation avancée
--------------------------------------------------------------------------------
-- 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 | doc
-: | : ----------------------------------------
1 | Entrez un lot par champ, n'utilisez pas 'GO'
2 | Les champs grandissent à mesure que vous tapez
3 | Utilisez les boutons [+] pour ajouter plus
4 | Voir les exemples ci-dessous pour une utilisation avancée
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 | doc
-: | : ----------------------------------------
1 | Entrez un lot par champ, n'utilisez pas 'GO'
2 | Les champs grandissent à mesure que vous tapez
3 | Utilisez les boutons [+] pour ajouter plus
4 | Voir les exemples ci-dessous pour une utilisation avancée