Wann werden die Werte für berechnete Spalten ermittelt?
- Wann wird der Wert abgerufen?
- Wann wird der Wert geändert?
- Ein andermal?
Ich vermute, dies ist eine unerfahrene Frage, da ich bei meinen Suchen nichts finde.
sql-server
computed-column
Shelby115
quelle
quelle
Dies ist sehr einfach selbst zu beweisen. Wir können eine Tabelle mit einer berechneten Spalte erstellen, die eine skalare benutzerdefinierte Funktion verwendet, und dann Pläne und Funktionsstatistiken vor und nach einer Aktualisierung und Auswahl überprüfen und sehen, wann eine Ausführung aufgezeichnet wird.
Nehmen wir an, wir haben diese Funktion:
Und dieser Tisch:
Überprüfen wir
sys.dm_exec_function_stats
(neu in SQL Server 2016 und Azure SQL-Datenbank) vor und nach dem Einfügen und anschließend nach einer Auswahl:Ich sehe keinen Funktionsaufruf am Insert, nur am Select.
Löschen Sie nun die Tabellen und wiederholen Sie den Vorgang. Ändern Sie diesmal die Spalte in
PERSISTED
:Und ich sehe das Gegenteil: Ich bekomme eine Ausführung auf dem Insert protokolliert, aber nicht auf dem Select.
Sie haben keine moderne Version von SQL Server
sys.dm_exec_function_stats
? Keine Sorge, dies ist auch in den Ausführungsplänen festgehalten .Für die nicht persistente Version können wir die Funktion, auf die verwiesen wird, nur in select sehen:
Während die persistierte Version nur die Berechnung beim Einfügen anzeigt:
Jetzt bringt Martin einen wichtigen Punkt in einem Kommentar vor : Das wird nicht immer wahr sein. Erstellen wir einen Index, der die persistierte berechnete Spalte nicht abdeckt, und führen Sie eine Abfrage aus, die diesen Index verwendet, und prüfen Sie, ob bei der Suche die Daten aus den vorhandenen persistierten Daten abgerufen werden, oder berechnen Sie die Daten zur Laufzeit (Funktion zum Löschen und erneuten Erstellen) und Tabelle hier):
Jetzt führen wir eine Abfrage aus, die den Index verwendet (tatsächlich wird der Index in diesem speziellen Fall standardmäßig verwendet, auch ohne eine where-Klausel):
Ich sehe zusätzliche Ausführungen in den Funktionsstatistiken und der Plan lügt nicht:
Die Antwort ist also IT-ABHÄNGIGKEIT . In diesem Fall hielt es SQL Server für billiger, die Werte neu zu berechnen, als Suchvorgänge durchzuführen. Dies kann sich aufgrund verschiedener Faktoren ändern. Verlassen Sie sich also nicht darauf. Dies kann in beide Richtungen geschehen, unabhängig davon, ob eine benutzerdefinierte Funktion verwendet wird oder nicht. Ich habe es hier nur verwendet, weil es so viel einfacher zu veranschaulichen war.
quelle
Die Antwort auf diese Frage lautet wirklich "es kommt darauf an". Ich bin gerade auf ein Beispiel gestoßen, in dem SQL Server den Index für die persistierte berechnete Spalte verwendet, aber die Funktion weiterhin ausführt, als ob die Werte von Anfang an nie persistiert würden. Möglicherweise hat dies mit dem Datentyp der Spalte (
nvarchar(37)
) oder möglicherweise mit der Größe der Tabelle (etwa 7 Millionen Zeilen) zu tun , doch SQL Server hat sichpersisted
in diesem speziellen Fall entschlossen, das Schlüsselwort zu ignorieren .In diesem Fall ist der Primärschlüssel in der Tabelle "TransactionID" (Transaktions-ID), bei der es sich ebenfalls um eine berechnete und beständige Spalte handelt. Der Ausführungsplan generiert einen Index-Scan und in einer Tabelle mit nur 7 Millionen Zeilen dauert die Ausführung dieser einfachen Abfrage mehr als 2-3 Minuten, da die Funktion für jede Zeile erneut ausgeführt wird und die Werte nicht beibehalten zu werden scheinen Der Index.
quelle