cameodski schreef op 01 november 2002 @ 23:33:
[...]
Oh, ik dacht dat we het over het verschil in snelheid tussen het wel en niet gebruiken van het keyword join hadden?
En niet over het verschil tussen select * en select veldnamen.
Ik ben het volledig met Cameodski eens. Over het al dan niet gebruiken van select * hebben we het al eens over gehad in een eerder topic en ik wil nu niet in herhalingen gaan vallen.
Vergeef me dat ik niet altijd even sterk ben om een en ander duidelijk te maken. Het op papier zetten van dergelijke argumenten is niet mijn sterkste kant en ik kan me levendig voorstellen dat ik soms verwarring schep
Het al dan niet gebruiken van het woord JOIN, het zou helemaal niets mogen uitmaken voor de optimizer qua snelheid. Het zoekpad dat de optimizer voorstelt zal exact gelijk moeten zijn. De vraag die dan blijft, is dat inderdaad zo, niet?
Wel, hier komt het antwoord voor Sybase, Oracle en MSSQL.
In zowel Sybase, Oracle en MSSQL (gebaseerd op Sybase) maakt het niets uit of je al dan niet gebruik maakt van JOIN. (Wacht even met verdere reacties, please ik ga hier eerst wat dieper op in) Het gebruik van het woord JOIN (of juist niet gebruiken ervan) heeft alleen te maken met de opmaak van de query. Dat de een een voorstander is van het gebruik van JOIN en een ander dit liever vermijdt is slechts een kwestie van smaak. De optimizer zal tot exact hetzelfde resultaat komen qua zoekpad (en dus ook qua snelheid).
Met name in stored procedures, triggers e.d. compileert de optimizer maar eenmaal de code en slaat het door hem voorgeslagen zoekpad op. Dit zoekpad zal de optimizer altijd opnieuw gebruiken zodra de stored procedure /trigger opnieuw wordt aangeroepen (tenzij ik de procedure/trigger opnieuw aanmaak of hercompileer!). Voor het bepalen van het zoekpad zal dan geen tijd meer verloren gaan en daar het zoekpad in beide gevallen exact hetzelfde is, zal het helemaal niets uitmaken in snelheid.
De vraag die dan blijft, hoe zit het dan met ad hoc queries? Is daar een verschil merkbaar? Ik zal een poging ondernemen (forgive me, indien ik niet iedereen overtuigen kan)
Ik ben al jaren actief als Technisch DB ontwerper voor een grote multi-user omgeving (meer dan 300 concurrent users) en heb me met name gespecialiseerd in het tunen van queries die een botleneck vormen in performance en kan melden dat zowel de volgorde van doorlopen van tabellen die gebruikt zijn in de join, als ook de gebruikte indexen een exacte kopie van elkaar zijn (als we het hebben over wel / niet JOIN gebruik).
Echter...., er zijn uitzonderingen!!! Tja, jammer maar helaas, maar het is nu niet anders. De optimizer is door mensen in elkaar gezet en zal nooit ofte nimmer in staat zijn in alle gevallen tot hetzelfde pad komen. (Heeft niets te maken met al dan niet gebruiken van JOIN)
(Een en ander hangt ook nog af van de statistics, maar zal dit niet nader toelichten, want daar is genoeg literatuur over te vinden en het heeft ook niets te maken met het al dan niet gebruik van JOIN)
Zo is er onder andere een tekortkoming in de (Sybase in ieder geval) optimizer wat betreft triggers. Ik zal maar een voorbeeld geven om dit te verduidelijken.
Stel ik wil in een trigger van een tabel, iets updaten in tabel b (om wat voor reden dan ook)
Voorbeeld 1
update b
set ditte = 1
where exists(select 1 from inserted where inserted.id = b.id)
Voorbeeld 2
update b
set ditte = 1
from inserted, b --Dit werkt onder Sybase
where b.id = inserted.id
In de meeste gevallen zal de optimizer exact hetzelfde zoekpad bepalen, echter... dat is helaas niet in 100% van de gevallen zo. Voorbeeld 1 zal in geval van de Sybase optimizer (en hoogstwaarschijnlijk ook andere RDBMS) wel eens problemen op kunnen leveren in een multi-user omgeving (om het maar een beetje complexer te maken dan het al is), er wordt soms om onverklaarbare redenen een tijdelijke Exclusive Table lock(!!!!) gelegd voor het vinden van geschikte rijen (die hij wordt opgeheven zodra de rijen gevonden zijn en begint met de update).
Voordat er mensen commentaar geven dat dit te maken heeft met het gebruik van exists, helaas dit heeft niets met exists te maken, want bij een select statement met exists komt hij in beide gevallen wel tot hetzelfde zoekpad.
Voor degene die query 1 uitvoert zal dit niet merkbaar zijn (tenzij er gewacht moet worden totdat de exclusive Table lock genomen kan worden), maar voor andere gebruikers die ook data van die tabel willen lezen, gedurende de transactie wel degelijk (Zij worden geblokt)
Zoals ik al eerder aangaf, lees eerst eens met name hoofdstuk 17 door van de Performance en Tuning guide (Volume 2) van Sybase door op de link die ik eerder reeds heb gegeven, dan wordt een en ander duidelijk. De meeste RDBMS werken op het Cost-based principe. En als je je dan toch eenmaal aan het verdiepen bent in de mysteries van de optimizer, dan raad ik aan ook eens de rest van de 3 volumes door te lezen, er zal een hele wereld voor je open gaan.