SQL Server Left Join Mit 'Oder' - Operator
Ich habe vier Tabellen, TopLevelParent, zwei mid-level-Tabellen MidParentA und MidParentB, und einer Untergeordneten Tabelle, die ein Elternteil MidParentA oder MidParentB (das Eine oder andere midParent muss vorhanden sein). Sowohl mid-level-Tabelle eine übergeordnete Tabelle der TopLevelParent.
Die Top-Level-Tabelle wie folgt Aussehen:
TopLevelId | Name
--------------------------
1 | name1
2 | name2
Den MidParent Tabellen wie folgt Aussehen:
MidParentAId | TopLevelParentId | MidParentBId | TopLevelParentId |
------------------------------------ ------------------------------------
1 | 1 | 1 | 1 |
2 | 1 | 2 | 1 |
Die Child-Tabelle wie folgt Aussehen:
ChildId | MidParentAId | MidParentBId
--------------------------------
1 | 1 | NULL
2 | NULL | 2
Benutzt habe ich die folgenden left join in einen größeren gespeicherte Prozedur, die das timing, und es sieht aus wie der or-operator auf die letzten left join ist der übeltäter:
SELECT *
FROM TopLevelParent tlp
LEFT JOIN MidParentA a ON tlp.TopLevelPatientId = a.TopLevelPatientId
LEFT JOIN MidParentB a ON tlp.TopLevelPatientId = b.TopLevelPatientId
LEFT JOIN Child c ON c.ParentAId = a.ParentAId OR c.ParentBId = b.ParentBId
Ist es ein schneller Weg, dies zu tun beitreten?
- gute Frage + gute Antworten
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gegeben, wie wenig die Abfrage ist ausgesetzt; eine sehr grobe Faustregel ist, zu ersetzen Oder mit einer Union zu vermeiden-Tabelle Scannen.
Sollten Sie kümmern sich mit Hilfe von Prädikaten, die im inneren Auf.
"Es ist sehr wichtig zu verstehen, dass, mit outer-joins, die ON-und WHERE-Klauseln spielen sehr unterschiedliche Rollen, und daher, Sie sind nicht austauschbar. Die WHERE-Klausel spielt immer noch eine einfache Filterung Rolle—nämlich, es hält wahre Fälle und verwirft die falsche und unbekannte Fälle. Verwenden Sie so etwas wie dieses und Prädikate in der where-Klausel. Aber die ON-Klausel nicht zu spielen einen einfachen Filterung Rolle, es ist eher mehr eine passende Rolle. In anderen Worten, eine Zeile in der erhaltenen Seite wird zurückgegeben, ob das Prädikat AUF eine übereinstimmung findet oder nicht. Also die AUF Prädikat nur bestimmt, welche Zeilen aus der nonpreserved Seite bekommen, abgestimmt auf die Zeilen von der erhaltenen Seite—nicht, ob die Zeilen zurückzugeben, die von der erhaltenen Seite." **Exam 70-461: Abfragen von Microsoft SQL Server 2012
Hier ist, was ich Tat, am Ende, der Ausführung down Zeit von 52 Sekunden auf 4 Sekunden.
Dadurch entfällt die Tabelle Scannen, was passiert war, als ich angepasst haben, die die top-level-Datensatz in seiner Mittellinie übergeordneten vorne, wenn es vorhanden ist, und machte es auf diesem Album.
Ich habe auch das gleiche getan mit dem Kind aufnehmen heißt, ich kann dann nur zusammen mit dem Kind aufnehmen, um die top-level-Datensatz auf der MidParentId, und ich nutze die IsMidParentA bit-flag, um zu differenzieren, wo es zwei identische MidParentIds (dh ein Id-1 für IsMidParentA und IsMidParentB).
Danke an alle die sich die Zeit genommen, Sie zu beantworten.
einen anderen Weg, es zu schreiben:
LEFT JOIN Child c ON c.ParentAId = COALESCE(a.ParentAId, b.ParentBId)
Bearbeiten
Ein möglicher Ansatz ist, die Abfrage zuerst die MidParentA und dann die MidParentB und dann
UNION
die Ergebnisse:Einer demo in SQLFiddle