Ich versuche, die Auswirkungen der Auswahl von Daten aus einer Ansicht auf die Leistung zu verstehen, wobei eine der Spalten in einer Ansicht von anderen Daten in der Originaltabelle abhängt.
Wird die Berechnung unabhängig davon durchgeführt, ob sich die berechnete Spalte in der Liste der ausgewählten Spalten befindet oder nicht?
Wenn ich einen Tisch hätte und die Ansicht so deklariert wäre
CREATE TABLE price_data (
ticker text, -- Ticker of the stock
ddate date, -- Date for this price
price float8, -- Closing price on this date
factor float8 -- Factor to convert this price to USD
);
CREATE VIEW prices AS
SELECT ticker,
ddate,
price,
factor,
price * factor as price_usd
FROM price_data
Würde diese Multiplikation in einer Abfrage wie der folgenden durchgeführt?
select ticker, ddate, price, factor from prices
Gibt es eine Referenz, die dies auf die eine oder andere Weise garantiert? Ich habe die Dokumentation zum Regelsystem in Postgres gelesen, aber ich denke, die Antwort liegt wirklich beim Optimierer, da nichts in der Dokumentation zum Regelsystem darauf hinweist, dass es nicht ausgewählt werden würde.
Ich vermute im obigen Fall, dass die Berechnung nicht durchgeführt wird. Ich habe die Ansicht geändert, um Division anstelle von Multiplikation zu verwenden, und ein 0
for factor
in eingefügt price_data
. Die obige Abfrage ist nicht fehlgeschlagen. Wenn die Abfrage jedoch geändert wurde, um die berechnete Spalte auszuwählen, ist die geänderte Abfrage fehlgeschlagen.
Gibt es eine Möglichkeit zu verstehen, welche Berechnungen durchgeführt werden, wenn a select
ausgeführt wird? Ich schätze, ich suche nach etwas Ähnlichem EXPLAIN
, das mir aber auch Auskunft über die durchgeführten Berechnungen gibt.
quelle
Antworten:
Wie @Laurenz sagte, ist Ihre Analyse korrekt: Der Optimierer vermeidet die Auswertung von Spaltenausdrücken, die das Ergebnis der Abfrage nicht beeinflussen (und Ihr Versuch, einen Fehler beim Teilen durch Null zu erzwingen, ist ein Beweis dafür).
Dies hängt davon ab, welche Spalten Sie auswählen, aber auch von der Volatilitätskategorie der Spaltenausdrücke. Dem Optimierer steht es frei, Funktionsaufrufe wegzulassen
immutable
und zustable
verwenden, wenn ihre Ausgabe nie verwendet wird, da sie das Ergebnis nicht beeinflussen können.volatile
Funktionen können jedoch Nebenwirkungen haben, sodass sie nicht so einfach optimiert werden können.Zum Beispiel:
Wenn nur die
volatile
Spalte ausgewählt ist:... dann, wie Sie sehen können,
stable_function()
fehlt in derexplain
Ausgabe, und das Fehlen einesNOTICE
bestätigt, dass dieser Aufruf weg optimiert wurde.Wenn
stable
jedoch stattdessen die Spalte ausgewählt ist:... dann sehen wir beide Spaltenausdrücke im Plan und die
NOTICE
s zeigen, dass beide Funktionen ausgeführt wurden.Es scheint keine explizite Erwähnung dieses Verhaltens in den Dokumenten zu geben, daher gibt es keine festen Garantien dafür, ob ein Ausdruck ausgewertet wird oder nicht, und Sie sollten sich nicht auf Nebenwirkungen verlassen, die Ihre Funktionsaufrufe haben könnten.
Wenn Ihre einzige Sorge jedoch die Leistung ist, können Sie, solange Sie Ihre Funktionen als
stable
oderimmutable
gegebenenfalls markieren , ziemlich sicher sein (insbesondere in einfachen Fällen wie diesen), dass sie nur bewertet werden, wenn sie benötigt werden.(Und während Sie dort Ihre Volatilitätserklärungen prüfen, möchten Sie möglicherweise auch die parallelen Sicherheitsflags setzen .)
quelle
Ihr Verdacht ist richtig und die Berechnung sollte nicht durchgeführt werden, wenn die Spalte nicht verwendet wird.
Um dies zu bestätigen, sehen Sie sich die Ausgabe von
EXPLAIN (VERBOSE)
für die Abfrage an, in der die zurückgegebenen Spalten angezeigt werden.quelle