Merkwürdiges Verhalten bei berechneten Spalten in SQL-Server

12

Während ich mein 70-433-Prüfungsbuch las, fiel mir etwas ein, bei dem ich sehe, dass es nicht funktioniert, aber ich glaube, dass es funktioniert. Die Passage lautete ungefähr so:

Die Spalte muss auch als PERSISTED gekennzeichnet sein. Dies bedeutet, dass SQL Server das Ergebnis des Ausdrucks der berechneten Spalte physisch in der Datenzeile speichert, anstatt es bei jedem Verweis in einer Abfrage zu berechnen.

Daraus verstehe ich zwei Dinge:

  1. Eine nicht persistierte berechnete Spalte wird jedes Mal berechnet, wenn in einer Abfrage auf sie verwiesen wird
  2. Da für die berechnete Spalte nichts gespeichert ist, kann vermutlich kein Index für die Spalte erstellt werden.

Nachdem ich es gelesen hatte, fand ich das etwas seltsam, da ich es in einem früheren Projekt geschafft habe, einen Index für eine nicht persistierte Spalte zu erstellen.

Wie kann ein Index für etwas erstellt werden, das nicht beibehalten wird und das auf lange Sicht schädlich ist?


Um dies zu beweisen, habe ich die folgende SQL-Anweisung ausgeführt:

CREATE TABLE testTable
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    telephone VARCHAR(14),
    c_areaCode AS (SUBSTRING(telephone,0,5)),
    cp_areaCode AS (SUBSTRING(telephone,0,5)) PERSISTED
)

INSERT INTO testTable VALUES('09823 000000');
INSERT INTO testTable VALUES('09824 000000');
INSERT INTO testTable VALUES('09825 000000');

CREATE NONCLUSTERED INDEX IX_NotPersisted ON testTable(c_areaCode);
CREATE NONCLUSTERED INDEX IX_Persisted ON testTable(cp_areaCode);

Führen Sie dann die folgenden Abfragen aus:

DBCC FREEPROCCACHE
DBCC FREESYSTEMCACHE('ALL');
DBCC DROPCLEANBUFFERS
GO
SELECT cp_areaCode FROM testTable;
GO
SELECT c_areaCode FROM testTable;

Wenn ich mir den Abfrageplan für den obigen Code angesehen habe, sehe ich, dass beide ausgewählten Abfragen den nicht persistierten Index verwenden. Wieder wie?

Bildbeschreibung hier eingeben

Stuart Blackler
quelle
Für diejenigen, die das Buch 70-433 haben, steht der zitierte Text oben auf Seite 111.
Stuart Blackler

Antworten:

9

2. Da für die berechnete Spalte nichts gespeichert ist, gehe ich davon aus, dass für die Spalte kein Index erstellt werden kann.

Diese Annahme ist nicht wahr - jede Art kann indiziert werden . Die berechnete Spalte muss in beiden Fällen deterministisch sein. Wenn die berechnete Spalte jedoch beibehalten wird, wird die Anforderung, dass die Berechnung ebenfalls präzise ist, gelockert (dh, es können Gleitkommaoperationen verwendet werden).

Wie kann ein Index für etwas erstellt werden, das nicht beibehalten wird und das auf lange Sicht schädlich ist?

Das Ergebnis der Funktion wird in beiden Fällen im Index "beibehalten" - der einzige Unterschied besteht darin, ob es in der Tabelle beibehalten wird.

Jack sagt, versuchen Sie es mit topanswers.xyz
quelle