Postgres Analog zu CROSS APPLY in SQL Server
Muss ich migrieren von SQL-Abfragen geschrieben für MS SQL Server 2005 auf PostgreSQL 9.1.
Was ist der beste Weg, um Ersatz für CROSS APPLY
in dieser Abfrage?
SELECT *
FROM V_CitizenVersions
CROSS APPLY
dbo.GetCitizenRecModified(Citizen, LastName, FirstName, MiddleName,
BirthYear, BirthMonth, BirthDay, ..... ) -- lots of params
GetCitizenRecModified()
Funktion ist eine Tabellenwertfunktion ist. Ich kann nicht Ort, den code dieser Funktion, denn es ist wirklich enorm, es macht einige schwierige Berechnungen und kann ich nicht aufgeben.
Sie nicht brauchen, cross apply in Postgres. Sie können eine Tabelle-Funktion genau wie eine Funktion. Einfach nur sich Ihnen anzuschließen.
Ich weiß, dass es uralt ist... @MartinSmith, dass ist nicht unbedingt der Fall auf MSSQL, wenn die Funktion der inline-table-valued-Sorte, siehe Paul White ' s schreiben auf, wie der MSSQL-query-Planer kann manchmal optimieren
CROSS APPLY
neu führt die TVF mit korrelierten Parameter, anstatt einmal ausführen und dann Zusammenfügen das Ergebnis.Ich weiß, dass es uralt ist... @MartinSmith, dass ist nicht unbedingt der Fall auf MSSQL, wenn die Funktion der inline-table-valued-Sorte, siehe Paul White ' s schreiben auf, wie der MSSQL-query-Planer kann manchmal optimieren
apply
in eine join
: sqlservercentral.com/articles/APPLY/69954 Da wir sehen nicht den original-code hier bin ich, darüber zu spekulieren, was passiert ist, basierend auf dem Kommentar re Leistung auf Erwin ' s Antwort.InformationsquelleAutor user1178399 | 2012-07-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Postgres 9.3 oder später eine
LATERAL
join:Warum
LEFT JOIN LATERAL ... ON true
?Für älteren Versionen, es gibt einen sehr einfachen Weg, das zu erreichen, was ich denke Sie versuchen, mit einer set-returning Funktion (
ZURÜCKGIBT TABLE
oderRETURNS SETOF record
ODERZURÜCKGIBT record
):Die Funktion berechnet Werte einmal für jede Zeile der äußeren Abfrage. Wenn die Funktion mehrere Zeilen zurückgibt, was Zeilen, multipliziert sich entsprechend. Alle Klammern sind syntaktisch erforderlich zersetzen, eine Zeile geben. Die Tabelle Funktion könnte wie folgt Aussehen:
Müssen Sie wickeln Sie diese in einer Unterabfrage oder CTE, wenn Sie sich bewerben möchten eine
WHERE
Klausel, weil die Spalten nicht sichtbar sind auf dem gleichen Niveau. (Und es ist besser für die performance sowieso, da Sie eine wiederholte Auswertung für jeden Ausgang Spalte von der Funktion):Gibt es mehrere andere Möglichkeiten, dies zu tun oder etwas ähnliches. Es hängt alles davon ab, was Sie genau möchten.
Es ist praktisch unmöglich, zu kommentieren, ohne zu wissen, die spielen viele Faktoren eine Rolle. Ich würde spekulieren, dass die Leistung verbessert werden kann.
Ich würde vorschlagen, dass der Grund für den Leistungsunterschied ist, dass der ursprüngliche MSSQL Abfrage ist wahrscheinlich nicht die Ausführung der Funktion für jede Zeile. Die Funktion ist wahrscheinlich eine inline-table-valued-function (ITVF), und der Abfrageoptimierer ausgeführt hat, ist als
join
eher als eine korrelierte Abfrage für jede Zeile. In diesem Fall mitlateral
ist ein unfairer Vergleich. In jedem rdbms, ausführen einer benutzerdefinierten (in sql) - Funktion für jede Zeile ist eine schreckliche Idee. Es ist ein gutes Beispiel dafür, wie MSSQL query planner optimieren können ITVF hier: sqlservercentral.com/articles/APPLY/69954InformationsquelleAutor Erwin Brandstetter
Necromancing:
Neues in PostgreSQL 9.3:
Den SEITLICHEN Stichwort
left | right | inner JOIN SEITLICHEN
INNER JOIN LATERAL
ist das gleiche wieCROSS APPLY
und
LEFT JOIN LATERAL
ist das gleiche wieOUTER APPLY
Beispiel:
InformationsquelleAutor Stefan Steiger
Ich mag Erwin Brandstetter die Antwort aber ich habe entdeckt, dass ein performance-problem:
beim laufen
Den f_citizen_rec_modified Funktion lief 1 mal für jede Spalte gibt es (multipliziert jede Zeile in v_citizenversions). Ich habe nicht finden die Dokumentation für diesen Effekt, sondern war in der Lage, ableiten, die es durch Debuggen. Nun stellt sich die Frage, wie können wir diesen Effekt (vor 9.3, wo die seitlichen Verknüpfungen verfügbar sind) ohne diese leistungsmindernden Nebenwirkungen?
Update: ich scheine zu haben eine Antwort gefunden. Schreiben Sie die Abfrage als folgt:
Der wichtigste Unterschied immer die raw-Funktion Ergebnisse erste (innere Unterabfrage) und dann Verpackung, die in einer anderen select -, Büsten, diese Ergebnisse in die Spalten. Getestet wurde dies auf PG 9.2
InformationsquelleAutor Joe Love
Dieser link wird angezeigt, um zu zeigen, wie es in Postgres 9.0+:
PostgreSQL: die Parametrisierung eines rekursiven Allgemeinen Tabellenausdrucks
Es ist weiter unten auf der Seite im Abschnitt "Emulation CROSS APPLY-mit set-returning functions". Bitte beachten Sie die Liste der Einschränkungen nach dem Beispiel.
InformationsquelleAutor Matthew Wood