select *
from A outer join B on A.Key = B.FKey
where A.Key is null
select *
from B
where B.FKey not in (select A.Key from A)
News:
|
Auch mit den Informationen über DBMS und Mengengerüst gibt es nur eine Antwort: "Es ist die Anfrage schneller, die schneller ist", denn es hängt noch von anderen Faktoren ab (siehe unten). Objektive Optimierungsansätze sind aber
1) [code]select B.*[/code] statt [code]select *[/code] 2) [b]Ausprobieren[/b] der 3. Variante mit [code]where not exists (select * from A ...)[/code] – BeachBlocker 08.09.2009
|
|
|
SELECT *
FROM B
WHERE NOT EXISTS (SELECT Key from A WHERE Key = B.FKey)
|
|
|
|
Richtig und wichtig! Zuviele Spalten können z.B. verhindern, dass der richtige Index verwendet wird.
Ein Index auf B.fKey z.B. bringt nichts, wenn B.* selektiert wird. Das erste Besipiel mit "select *" ist sogar noch schlimmer, weil dann noch aus A alle Felder geholt werden müssen, die aber per Definition alle NULL enthalten müsssen, also keinerlei Information bringen. Wenn es nur darum geht sicherzustelen, daß der Fall "B.fKey not in (A.Key)" nicht auftritt, ist dann sogar ein "select count(*)" schneller als ein "select B.*" – BeachBlocker 08.09.2009
|
SELECT B.*
FROM B
LEFT JOIN A ON A.Key = B.FKey
WHERE A.Key IS NULL;
|
Ich will nun die Zeilen aus B haben, die einen Key haben, der nicht in A vorkommt
select *
from A outer join B on A.Key = B.FKey
where A.Key is null
select *
from B
where B.FKey not in (select A.Key from A)
|
select * from A outer join B on A.Key = B.FKey where A.Key is null
SELECT * FROM B WHERE NOT EXISTS (SELECT Key from A WHERE Key = B.FKey)
select * from B where B.FKey not in (select A.Key from A)
|
Gute DB, böse DB ?
Ich würde nicht aufhören selber zu denken und dem Query-Optimierer der DB blind vertrauen. Ich habe bisher keinen Optimierer gesehen der absolut schlect formulierte Statements performant ausführt. – MiW 08.09.2009
|
||
Gute DBMS haben gute Optimierer; schlechte DBMS (z.B. ältere) haben schlechte Optimierer. SQL ist - absichtlich - so einfach aufgebaut, dass ein es möglich ist, gute Optimierer zu schreiben, die fast unabhängig vom Statement zum optimalen Ergebnis kommen. Aber niemand sollte deshalb aufhören zu denken. Man sollte sich aber zuerst auf ein gutes DB Design konzentrieren und dann erst wenn nötig SQL-Statement opimieren.
– BeachBlocker 08.09.2009
|
|
Deine Kommentare zum Ausführungsplan und dem Index unterstütze ich ganz, aber das meine ich mit Datenbankdesign. Die Notwendigkeit und Einflußmöglichkeit mit Umformulierungen schränken sich aber häufig ein auf die select_list. Ob du z.B. "in" oder "or" oder "union all" verwendest, joins oder sub selects vervorzugts hat dagegen häufig gar keinen Einfluß und wenn ja ist das nicht vorhersehbar, ob die Umformulierung nützlich oder schädlich ist. Wenn die Umformullierung heute hilft sagt das noch nichts für morgen aus, wenn sich zum Beispiel das Mengenrerüst geändert hat.
– BeachBlocker 09.09.2009
|
select * from A outer join B on A.Key = B.FKey where A.Key is null
select * from A, B
SELECT * FROM B WHERE NOT EXISTS (SELECT Key from A WHERE Key = B.FKey)
select * from B where B.FKey not in (select A.Key from A)
|
Die Formulierung der SQL Abfrage sagt nicht darüber aus, wie das DBMS das Ergebnis intern berechnet. Das DBMS muß nichts, außer das richtige Ergebnis liefern.
Beide Varianten "NOT EXISTS (SELECT * FROM A ...)" und "B.FKey not in (SELECT ...)" werden auf meinem MSSQL 2008 exakt gleich abgearbeitet, und zwar mit einem Merge Join. Und wie r.stropek bereits ausführte, ist das unter (seinen und meinen) Umständen die schnellste. – BeachBlocker 09.09.2009
|
Dein erstes Beispiel müßte explizit ein RIGHT OUTER JOIN sein, damit das gewünschte Ergebnis erzielt wird.