Comportement étrange avec les colonnes calculées dans SQL-Server

12

En lisant mon livre d'examens 70-433, j'ai pensé à quelque chose que je ne vois pas fonctionner, mais je pense que oui. Le passage lisait quelque chose comme:

La colonne doit également être marquée comme PERSISTED , ce qui signifie que SQL Server stocke physiquement le résultat de l'expression de la colonne calculée dans la ligne de données au lieu de le calculer chaque fois qu'il est référencé dans une requête.

J'en comprends deux choses:

  1. Une colonne calculée non persistante est calculée chaque fois qu'elle est référencée dans une requête
  2. Étant donné que rien n'est stocké pour la colonne calculée, je suppose qu'aucun index ne peut être créé pour la colonne.

Après l'avoir lu, j'ai pensé que c'était un peu étrange car j'ai réussi à créer un index sur une colonne non persistante dans un projet précédent.

Comment créer un index pour quelque chose qui ne persiste pas et est-ce nuisible à long terme?


Pour le prouver, j'ai exécuté l'instruction SQL suivante:

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

Et puis exécutez les requêtes suivantes:

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

Après avoir examiné le plan de requête pour le code ci-dessus, je peux voir que les deux requêtes sélectionnées utilisent l'index non persistant. Encore une fois, comment?

entrez la description de l'image ici

Stuart Blackler
la source
Pour ceux qui ont le livre 70-433, le texte cité est en haut de la page 111.
Stuart Blackler

Réponses:

9

2.Parce que rien n'est stocké pour la colonne calculée, je suppose qu'aucun index ne peut être créé pour la colonne.

Cette hypothèse n'est pas vraie - les deux types peuvent être indexés . La colonne calculée doit être déterministe dans les deux cas, mais lorsque la colonne calculée est persistante, l'exigence que le calcul soit également précis est assouplie (c'est-à-dire qu'elle peut impliquer des opérations en virgule flottante).

Comment créer un index pour quelque chose qui n'est pas persistant et est-ce nuisible à long terme?

Le résultat de la fonction est «persistant» dans l'index dans les deux cas - la seule différence est de savoir si elle est persistante dans le tableau.

Jack dit d'essayer topanswers.xyz
la source