2009-05-22 5 views
25

Je l'instruction suivante:Pourquoi est-ce que je provoque une mise à jour de l'index cluster?

UPDATE TOP(1) dbo.userAccountInfo 
SET   Flags = Flags | @AddValue 
WHERE   ID = @ID; 

La colonne « ID » est une clé primaire INT avec des contraintes IDENTITY. Les drapeaux sont un BIGINT NON NULL.

Le chemin d'exécution indique qu'une mise à jour d'index cluster est en cours. Une opération très coûteuse. Il n'y a pas d'index couvrant les drapeaux ou les ID, sauf pour la clé primaire. Je me sens comme le chemin d'exécution réelle devrait être:

Clustered Index Seek => Mise à jour

+0

Vous êtes définitivement certain que l'index ne regroupe pas et ne couvre pas le champ [Drapeaux]? –

+0

Qu'est-ce qui est avec le TOP (1) dans la requête? – BradC

+0

@ Inconnu Google: J'ai seulement un idx non clusterisé sur cette table. Cela n'affecte ni les ID ni les drapeaux. @ BradC: C'est un peu de verbosité dans ma déclaration. "Cette déclaration affectera exactement un utilisateur." Mais ne sert vraiment à rien. – Kivin

Répondre

27

Tables sont disponibles en deux saveurs: les index clusterisés et des tas. Vous avez une contrainte PRIMARY KEY donc vous avez créé implicitement un index cluster. Vous devez aller à longueur supplémentaire au cours de la création de table pour ce pas à se produire. Toute mise à jour de la «table» est une mise à jour de l'index cluster, puisque l'index cluster est la table. En ce qui concerne la mise à jour de l'index clusterisé étant une «opération très coûteuse», il s'agit maintenant d'une légende urbaine entourant la désinformation de base sur le fonctionnement d'une base de données. L'instruction correcte est «une mise à jour d'index clusterisée affectant la clé en cluster doit mettre à jour tous les index non mis en cluster».

+0

C'est vraiment dommage qu'il y ait tellement de ... légendes urbaines, comme vous le dites ... entourant les RDB. J'ai écrasé une poignée d'entre eux dans les quelques semaines où j'ai écrit SQL. Puis-je supposer sans risque que, tant que je ne mets pas à jour l'identifiant, je ne provoquerai pas une opération (potentiellement) très coûteuse sur les données en cluster? – Kivin

+2

oui, c'est correct. – BradC

+5

La mise à jour de l'ID nécessiterait une mise à jour dans * tous * les autres index. La mise à jour de toute autre colonne faisant partie d'un index nécessiterait une mise à jour de ces index. Une colonne qui ne fait partie d'aucun index (clé ou colonne contenue) ne provoquerait aucune mise à jour supplémentaire. E.g. Si vous avez un index sur Flags, votre mise à jour entraîne une mise à jour supplémentaire pour conserver cet index. Je ne m'inquiéterais pas beaucoup au sujet des mises à jour à moins que je n'indique que l'un soit mauvais. Le plus souvent, les lectures non optimisées (balayages) constituent le problème. BTW, à quoi sert le TOP (1)? L'identité est PK, n'est-ce pas? –

10

L'index cluster est la table physique, donc chaque fois que vous mettez à jour une ligne, vous êtes mise à jour du cluster indice.

Voir this MSDN article

+0

Je sens que je ne devrais faire une mise à jour de l'index cluster que si j'affecte la clé primaire. Mais je comprends votre point. Je suppose que j'ai été un peu endoctriné pour penser que les mises à jour d'index clusterisées sont une chose dangereuse. – Kivin

+1

Un moyen d'éviter cela? – Serge

Questions connexes