Quand les valeurs des colonnes calculées sont-elles déterminées?
- Lorsque la valeur est récupérée?
- Lorsque la valeur est modifiée?
- Une autre fois?
Je suppose que c'est une question novice car je ne trouve rien dans mes recherches.
sql-server
computed-column
Shelby115
la source
la source
C'est très facile à prouver par vous-même. Nous pouvons créer une table avec une colonne calculée qui utilise une fonction définie par l'utilisateur scalaire, puis vérifier les plans et les statistiques de fonction avant et après une mise à jour et sélectionner, et voir quand une exécution est enregistrée.
Disons que nous avons cette fonction:
Et ce tableau:
Vérifions
sys.dm_exec_function_stats
(nouveau dans SQL Server 2016 et Azure SQL Database) avant et après une insertion, puis après une sélection:Je ne vois aucun appel de fonction sur l'insert, uniquement sur la sélection.
Maintenant, déposez les tables et recommencez, en changeant cette fois la colonne en
PERSISTED
:Et je vois le contraire se produire: j'obtiens une exécution enregistrée sur l'insert, mais pas sur la sélection.
Vous n'avez pas de version suffisamment moderne de SQL Server à utiliser
sys.dm_exec_function_stats
? Pas de soucis, cela est également reflété dans les plans d'exécution .Pour la version non persistante, nous pouvons voir la fonction référencée uniquement dans la sélection:
Alors que la version persistante ne montre que le calcul se produisant lors de l'insertion:
Maintenant, Martin soulève un grand point dans un commentaire : ce ne sera pas toujours vrai. Créons un index qui ne couvre pas la colonne calculée persistante, et exécutons une requête qui utilise cet index, et voyons si la recherche obtient les données des données persistantes existantes, ou calcule les données au moment de l'exécution (fonction de suppression et de recréation et tableau ici):
Maintenant, nous allons exécuter une requête qui utilise l'index (en fait, il utilise l'index par défaut dans ce cas spécifique de toute façon, même sans clause where):
Je vois des exécutions supplémentaires dans les statistiques de fonction, et le plan ne ment pas:
Donc, la réponse est IT DEPENDS . Dans ce cas, SQL Server pensait qu'il serait moins coûteux de recalculer les valeurs que d'effectuer des recherches. Cela pourrait changer en raison de divers facteurs, alors ne vous y fiez pas. Et cela peut se produire dans les deux sens, qu'une fonction définie par l'utilisateur soit utilisée ou non; Je ne l'ai utilisé ici que parce que c'était plus facile à illustrer.
la source
La réponse à cette question est vraiment "cela dépend". Je viens de parcourir un exemple où SQL Server utilise l'index sur la colonne calculée persistante mais il exécute toujours la fonction, comme si les valeurs n'étaient jamais persistantes pour commencer. Cela peut avoir à voir avec le type de données de la colonne (
nvarchar(37)
) ou peut-être la taille de la table (environ 7 millions de lignes), mais SQL Server a décidé d'ignorer lepersisted
mot clé, semble-t-il, dans ce cas particulier.Dans ce cas, la clé primaire de la table est TransactionID, qui est également une colonne calculée et persistante. Le plan d'exécution génère un balayage d'index et dans une table avec seulement 7 millions de lignes, cette requête simple prend plus de 2 à 3 minutes pour s'exécuter car la fonction est exécutée à nouveau sur chaque ligne et les valeurs ne semblent pas être persistées dans l'index.
la source