Strano comportamento con le colonne calcolate in SQL Server


12

Mentre leggevo il mio libro degli esami 70-433, ho pensato a qualcosa che posso vedere non funzionare, ma credo che lo faccia. Il passaggio legge qualcosa del tipo:

La colonna deve inoltre essere contrassegnata come PERSISTED , il che significa che SQL Server memorizza fisicamente il risultato dell'espressione della colonna calcolata nella riga di dati anziché calcolarlo ogni volta che viene indicato in una query.

Da questo capisco due cose:

  1. Una colonna calcolata non persistente viene calcolata ogni volta che viene referenziata in una query
  2. Poiché non viene memorizzato nulla per la colonna calcolata, suppongo che non sia possibile creare un indice per la colonna.

Dopo averlo letto, ho pensato che fosse un po 'strano dato che sono riuscito a creare un indice su una colonna non persistente in un progetto precedente.

Come si può creare un indice per qualcosa che non è persistente ed è dannoso a lungo termine?


Per dimostrarlo, ho eseguito la seguente istruzione SQL:

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);

E quindi eseguire le seguenti query:

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

Dopo aver esaminato il piano di query per il codice precedente, posso vedere che entrambe le query selezionate utilizzano l'indice non persistente. Ancora una volta, come?

inserisci qui la descrizione dell'immagine


Per quelli che hanno il libro 70-433, il testo citato è in cima alla pagina 111.
Stuart Blackler

Risposte:


9

2. Poiché non è stato memorizzato nulla per la colonna calcolata, suppongo che non sia possibile creare un indice per la colonna.

Questa ipotesi non è vera: entrambi i tipi possono essere indicizzati . La colonna calcolata deve essere deterministica in entrambi i casi, ma quando la colonna calcolata è persistente, viene meno il requisito che anche il calcolo sia preciso (cioè può comportare operazioni in virgola mobile).

Come si può creare un indice per qualcosa che non è persistente ed è dannoso a lungo termine?

Il risultato della funzione è 'persistente' nell'indice in entrambi i casi - l'unica differenza è se è persistente nella tabella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.