Effet d'un index sur les instructions de mise à jour lorsque la colonne de mise à jour n'est pas dans un index

16

Je vois constamment des gens disent que les indices ralentissent update, deleteet insert. Ceci est utilisé comme une instruction générale, comme s'il s'agissait d'un absolu.

Tout en ajustant ma base de données pour améliorer les performances, je continue de rencontrer cette situation qui semble contredire logiquement cette règle pour moi, et nulle part je ne peux trouver quelqu'un dire ou expliquer de quelque manière que ce soit autrement.

Dans SQL Server, et je pense / présume la plupart des autres SGBD, vos index sont créés en fonction des colonnes spécifiques que vous spécifiez. Les insertions et les suppressions affecteront toujours une ligne entière, il n'y a donc aucun moyen qu'elles n'affectent pas l'index, mais les mises à jour semblent un peu plus uniques, elles peuvent spécifiquement affecter uniquement certaines colonnes.

Si j'ai des colonnes qui ne sont incluses dans aucun index et que je les mets à jour, sont-elles ralenties simplement parce que j'ai un index sur d'autres colonnes de cette table?

Par exemple, disons dans ma Usertable que j'ai un ou deux index, la clé primaire qui est une colonne Identity / Auto Increment, et éventuellement une autre sur une colonne de clé étrangère.
Si je mets à jour une colonne sans l'index directement dessus, comme par exemple leur numéro de téléphone ou leur adresse, cette mise à jour est-elle ralentie parce que j'ai des index sur cette table sur d'autres colonnes dans les deux situations? Les colonnes que je mets à jour ne sont pas dans des index, donc logiquement, les index ne devraient pas être mis à jour, n'est-ce pas? Si quoi que ce soit, je pense qu'ils sont accélérés si j'utilise les index de la clause WHERE.

Ryan
la source
so there is no way they will not affect the indexsauf pour les index filtrés ...
usr
Je pense que l'index non couvert et non groupé contient des pointeurs vers des enregistrements (généralement dans les nœuds terminaux d'index cluster de la table). Je penserais qu'une situation pour provoquer un ralentissement pendant une MISE À JOUR (d'un attribut non inclus) pourrait être une situation où la MISE À JOUR a provoqué le déplacement de l'enregistrement dans l'index clusterisé. Je ne sais toujours pas si un mouvement entraînerait la modification du pointeur, OU si le pointeur est simplement une valeur KEY dans l'index clusterisé, auquel cas la mise à jour possible de l'emplacement n'aurait pas d'importance car le système ferait simplement une recherche KEY pour obtenir la valeur d'enregistrement.
Jmoney38

Réponses:

6

Vous avez raison: la mise à jour d'une colonne non indexée n'entraînera pas de modifications des index. Dans un cas simple, il n'y aurait pas non plus d'impact global sur la table.

Si une requête peut utiliser l'index pour rechercher des données, cela peut accélérer la recherche, mais le comportement exact (selon votre marque SQL) peut différer des autres marques SQL. (J'utilise principalement Microsoft SQL Server.)

Bien sûr, la mise à jour d'une colonne avec un volume de données significativement plus élevé peut entraîner un déplacement des lignes vers différentes pages, et cetera.

RLF
la source
1
SQL Server est mentionné dans l'OP, j'ai ajouté une balise, donc je pense que vous pouvez supposer SQL Server
Tom V - Team Monica
10

Pour un système moderne relativement rapide, l'ajout d'un seul index à une table OLTP sera probablement pratiquement indétectable du point de vue des performances pour la grande majorité des systèmes . Cela dit, vous ne devez pas créer d'index inutiles et vous ne devriez probablement pas créer d'index à une seule colonne pour chaque colonne d'une table.

Vous avez raison de supposer que pour de nombreuses requêtes, la présence d'index utiles entraînera une amélioration très sensible de la vitesse.

Bien que votre question semble concerner les performances, il existe plusieurs autres problèmes potentiels liés à l'ajout d'index, notamment, mais sans s'y limiter:

  1. Le temps requis pour créer l'index peut entraîner un blocage pendant que l'index est ajouté à la table. La serrure est de courte durée et ne créera probablement pas de gros problème.

  2. Les modifications d'index entraînent l'annulation des plans d'exécution pour tous les plans faisant référence à la table sous-jacente. Lorsque ces plans d'exécution sont recompilés, les performances peuvent changer négativement pour certaines requêtes.

  3. Les modifications d'index peuvent entraîner des requêtes renvoyant des erreurs là où aucune n'a été retournée précédemment. Prenons le cas d'un index filtré qui a été utilisé pour renvoyer des dates contenues dans un champ varchar; si le filtre a supprimé toutes les lignes qui n'étaient pas des dates et que ce filtre a été modifié par la suite, les requêtes qui s'appuyaient sur cet index peuvent désormais échouer lors de la tentative de conversion de données non datées.

  4. Un nouvel index peut entraîner un changement de l'ordre d'exécution, entraînant des blocages possibles survenant là où ils ne s'étaient pas produits auparavant.

Max Vernon
la source
"Le chemin de code requis pour une mise à jour lorsque l'index ne sera pas affecté doit encore être évalué", ce n'est pas vrai. La phase de compilation / optimisation saura très bien quels index doivent être mis à jour, le cas échéant, et créera le plan en conséquence. Une instruction UPDATE qui ne modifie pas (déclare dans la liste SET) les colonnes d'un index (y compris les colonnes INCLUDE et clés en cluster) n'aura pas à mettre à jour cet index, et la phase d'exécution ne le touchera même pas. DELETE et INSERT touchent évidemment toutes les colonnes (logiquement) et doivent mettre à jour tous les index.
Remus Rusanu
@RemusRusanu mais n'aura-t-il pas besoin d'être évalué si l'index peut être utilisé pour localiser les lignes qui doivent être mises à jour?
Tom V - Team Monica
@RemusRusanu - Je suppose qu'une fois que le QO a compilé un plan, plus de CPU n'est nécessaire; cependant, pour que le plan soit compilé, il doit certainement le faire. Si les plans sont compilés fréquemment, cela pourrait faire une très légère différence.
Max Vernon
@TomV utilisant l'index pour localiser les lignes candidates à la suppression / mise à jour est un sujet entièrement différent. Si tel est le cas, les avantages de la localisation des lignes via un index devraient dépasser tous les problèmes de coût de maintenance d'index.
Remus Rusanu
@MaxVernon Je dirais qu'il n'y a pas de scénario valide de recompilations fréquentes de DML (UPDATE). J'achète certains cas pour des recompilations valides (inévitables?) Pour les requêtes ad hoc. Mais DML? Quel type d'application pourrait créer des instructions UPDATE uniques et ad hoc? Les recompilations fréquentes avec DML crient à voix haute "Paramètre-moi".
Remus Rusanu
-2

Si l'opération de mise à jour cible une colonne non indexée de taille fixe (comme un entier), elle ne devrait pas être lente de manière générale, mais par rapport à une instruction select, la mise à jour doit éventuellement être également écrite sur le disque lent.

Sorin
la source