Welches ist die bessere Abfrage, um zu prüfen, ob es Kinder zu einem Datensatz in gleicher Tabelle gibt?

25/02/2008 - 09:28 von Andy Dorwald | Report spam
Hallo NG,

hatte diese Frage letzte Woche auch schon in "MS.Public.de.vb.Datenbank"
gepostet. Bin mir aber unsicher, ob es dort vielleicht falsch ist, weil es
ja eigentlich um eine Abfrage im SQL-Server geht. Daher nun hier in
"MS.Public.de.vb.sqlserver". Ich hoffe, Ihr seht es nicht als Crossposting!

Um in einer hierarischen Datenablage herauszufinden, ob es zu einem Knoten
auch "Kinder" gibt, hatte ich bisher folgendes Statement eingesetzt:

SELECT DISTINCT Tabl.*,CONVERT(BIT,Kinder.NodeTyp) AS Kind FROM Tabl LEFT
JOIN Tabl AS Kinder ON Tabl.ID = Kinder.ParentID

...dabei gilt, wenn Kind NOT NULL, dann existieren welche!

Jetzt habe ich einen anderen Weg (mit einem Subselect!) herausgefunden und
bin mir unsicher, ob dieser vielleicht doch der bessere ist, da ich mit das
Ergebnis des "Ausführungsplans" nicht richtig deuten kann:

SELECT *, (SELECT TOP 1 NodeTyp FROM Tabl AS T WHERE T.ParentID=Tabl.ID) AS
Kind FROM Tabl

...dabei gilt, wenn Kind NOT NULL, dann existieren welche!

Frage1: Könnte mir jemand sagen, ob der Weg über ein Subselect
besser/performanter ist?
Frage2: Kennt Ihr ggf. noch einen weiteren, noch besseren Weg?
Frage3: Vielleicht sogar noch einen Tipp, wie man so einen Ausführungsplan
deutet?

Hier das Ergebnis des Query-Ausführungsplans:

Variante1:
1. Sort/Distinct Sort Kosten: 20%
2. Nested Loops/Left Outer Join Kosten:: 20%
3. Tabl.ixParent Kosten: 60%

Variante2:
1. Bookmark Lookup Kosten: 25%
2. Tabl.ixParent Kosten: 75%

Viele Gruesse
Andy
 

Lesen sie die antworten

#1 Hannes Brunner
25/02/2008 - 10:45 | Warnen spam
Hallo Andy,

Andy Dorwald schrieb:
Hallo NG,

hatte diese Frage letzte Woche auch schon in "MS.Public.de.vb.Datenbank"
gepostet. Bin mir aber unsicher, ob es dort vielleicht falsch ist, weil es
ja eigentlich um eine Abfrage im SQL-Server geht. Daher nun hier in
"MS.Public.de.vb.sqlserver". Ich hoffe, Ihr seht es nicht als Crossposting!

Um in einer hierarischen Datenablage herauszufinden, ob es zu einem Knoten
auch "Kinder" gibt, hatte ich bisher folgendes Statement eingesetzt:

SELECT DISTINCT Tabl.*,CONVERT(BIT,Kinder.NodeTyp) AS Kind FROM Tabl LEFT
JOIN Tabl AS Kinder ON Tabl.ID = Kinder.ParentID

...dabei gilt, wenn Kind NOT NULL, dann existieren welche!

Jetzt habe ich einen anderen Weg (mit einem Subselect!) herausgefunden und
bin mir unsicher, ob dieser vielleicht doch der bessere ist, da ich mit das
Ergebnis des "Ausführungsplans" nicht richtig deuten kann:

SELECT *, (SELECT TOP 1 NodeTyp FROM Tabl AS T WHERE T.ParentID=Tabl.ID) AS
Kind FROM Tabl



TOP ohne ORDER BY macht eigentlich wenig Sinn. Aber offensichtlich
interessiert dich NodeTyp ja gar nicht. Dann wàre eine Abfrage mit
EXISTS besser:

SELECT *,
CASE WHEN EXISTS(SELECT * FROM Tabl AS T WHERE T.ParentID=Tabl.ID)
THEN CONVERT(BIT, 1) ELSE CONVERT(BIT, 0) END AS Kind
FROM Tabl

Variante1:
1. Sort/Distinct Sort Kosten: 20%
2. Nested Loops/Left Outer Join Kosten:: 20%
3. Tabl.ixParent Kosten: 60%

Variante2:
1. Bookmark Lookup Kosten: 25%
2. Tabl.ixParent Kosten: 75%



Jetzt müsste der Bookmark Lookup, der nur wg. NodeTyp drin war, wegfallen.

Interessant wàre noch die Info über den Verzweigungsgrad, sprich
wieviele Kinder es im Schnitt gibt.

Übrigens, solange du im àußeren Select kein WHERE drin hast dürften die
Überlegungen eher theoretischer Natur sein da sowieso die ganze Tabelle
eingelesen werden muss und I/O Operation bekanntlich am teuersten sind.

Gruß
Hannes

Ähnliche fragen