Vergleichsgruppe von VS Over Partition von
-
27-10-2019 - |
Frage
Unter der Annahme eines Tisches CAR
mit zwei Spalten CAR_ID (int)
und VERSION (int)
.
Ich möchte die maximale Version jedes Autos abrufen.
Es gibt also zwei Lösungen (zumindest):
select car_id, max(version) as max_version
from car
group by car_id;
Oder :
select car_id, max_version
from ( select car_id, version
, max(version) over (partition by car_id) as max_version
from car
) max_ver
where max_ver.version = max_ver.max_version
Sind diese beiden Abfragen ähnlich Performant?
Lösung
Ja, es kann sich auswirken
Die zweite Abfrage ist ein Beispiel für die Inline -Ansicht. Es ist eine sehr nützliche Methode zum Ausführen von Berichten mit verschiedenen Arten von Zählungen oder Verwendung von Gesamtfunktionen damit.
Oracle führt die Unterabfrage aus und verwendet dann die resultierenden Zeilen als Ansicht in der From -Klausel.
Wenn wir über die Leistung berücksichtigen, empfehlen Sie immer die Inline -Ansicht, anstatt einen anderen Unterabbildungsart zu wählen.
Und noch eine Sache, die die zweite Abfrage alle Max -Datensätze gibt, während Sie zuerst nur einen Max -Rekord geben.
Andere Tipps
Ich weiß, dass dies extrem alt ist, aber ich dachte, es sollte darauf hingewiesen werden.
select car_id, max_version
from (select car_id
, version
, max(version) over (partition by car_id) as max_version
from car ) max_ver
where max_ver.version = max_ver.max_version
Ich bin mir nicht sicher, warum Sie so optional zwei gemacht haben. In diesem Fall sollte der Sub -Select theoretisch langsamer sein, da Sie aus derselben Tabelle 2x ausgewählt und dann die Ergebnisse an sich selbst verbinden.
Entfernen Sie einfach die Version aus Ihrer Inline -Ansicht und sie sind dasselbe.
select car_id, max(version) over (partition by car_id) as max_version
from car
Die Leistung hängt wirklich von dem Optimierer in dieser Situation ab, aber ja, die AS Original -Antwort deutet auf Inline -Ansichten hin, da sie enge Ergebnisse leisten. Dies ist zwar kein gutes Beispiel, es ist die gleiche Tabelle ohne Filter in der angegebenen Auswahl.
Die Partitionierung ist auch hilfreich, wenn Sie viele Spalten auswählen, jedoch unterschiedliche Aggregationen benötigen, die zum Ergebnissatz passen. Andernfalls sind Sie gezwungen, nach jeder anderen Spalte zu gruppieren.
Es hängt von Ihrem Indexierungsschema und der Datenmenge in der Tabelle ab. Der Optimierer trifft wahrscheinlich unterschiedliche Entscheidungen auf der Grundlage der Daten, die sich tatsächlich in der Tabelle befinden.
Ich habe festgestellt, dass zumindest in SQL Server (ich weiß, dass Sie nach Oracle gefragt haben), dass der Optimierer mit größerer Wahrscheinlichkeit einen vollständigen Scan mit der Partition per Abfrage gegen die Gruppe durch Abfrage durchführt. Dies ist jedoch nur in Fällen, in denen Sie einen Index haben, der Car_id und Version (Desc) enthält.
Die Moral der Geschichte ist, dass ich gründlich testen würde, um den richtigen zu wählen. Für kleine Tische spielt es keine Rolle. Für wirklich, wirklich große Datensätze kann auch nicht schnell sein ...