Database
 sql >> Base de données >  >> RDS >> Database

Optimisation de la base de données :index

J'ai remarqué que très peu de gens comprennent le fonctionnement des index dans SQL Server, en particulier les colonnes incluses. Néanmoins, les index sont un excellent moyen d'optimiser les requêtes. Au début, je n'avais pas non plus l'idée des colonnes incluses, mais mes expériences ont montré qu'elles sont très utiles.

Supposons que nous ayons la table et la requête suivantes :

CREATE TABLE Person (
 PersonID int,
 FirstName varchar(100),
 LastName varchar(100),
 Age int,
 …
 …
)

SELECT FirstName, LastName, Age
FROM Person
WHERE FirstName = 'John' and LastName = 'Smith'

Il est clair que PersonID est une clé primaire. Supposons que nous ayons un index par les noms et prénoms, appelons-le IX_Person_FirstNameLastName. Le plan d'exécution d'une telle requête se présentera comme suit :

  1. Recherche de toutes les lignes avec les prénoms et noms spécifiés à l'aide de l'arborescence d'index IX_Person_FirstNameLastName
  2. Détecter l'emplacement réel de la ligne sur le disque sur les feuilles d'index, se rendre à l'emplacement réel et lire l'âge.

Considérons maintenant que cette requête est exécutée assez fréquemment. Nous devons exécuter 2 étapes à chaque fois. Peut-il être optimisé ? Dans le cas de MS SQL Server, ce n'est pas un problème - vous pouvez inclure des valeurs directement dans l'index à l'aide de l'option INCLUDE.

CREATE INDEX IX_PERSON ON Person
( 
 FirstName,
 LastName
) 
INCLUDE(Age)

Désormais, ce champ n'est plus utilisé lors de l'indexation mais est inclus dans l'index. À quels problèmes pouvons-nous être confrontés à cet égard? Lorsque nous indexons une table par un certain champ, le serveur de base de données doit construire une arborescence d'index par ce champ. Cela signifie que nous devons changer l'arbre d'index lors du changement de valeur. Lorsque les valeurs sont modifiées de manière intensive, cela devient une tâche problématique et difficile pour le serveur. Lorsque la mise à jour devient trop massive, il est parfois plus facile de supprimer l'index. L'index optimise grandement la recherche mais affecte négativement les opérations d'insertion, de suppression et de mise à jour.
Si un champ est simplement inclus dans un index, il n'est pas utilisé lors de la construction d'une arborescence d'index et ne l'affecte pas, mais le la valeur peut être facilement trouvée sur la feuille de cet arbre. Lorsqu'une recherche par les noms et prénoms a lieu, le serveur recherche tous les noms et prénoms de l'arborescence, et lorsqu'il atteint la feuille (trouve la valeur d'index requise), puis en plus du pointeur vers l'emplacement physique des valeurs de ligne, il contient également des valeurs de champ incluses dans l'index. Cela signifie qu'il n'est pas nécessaire de franchir la deuxième étape pour basculer vers l'emplacement physique de la ligne et la lire à partir de là.

Comme vous n'avez pas besoin de changer l'arbre lors de la modification des données d'âge, tout cela n'affecte pas beaucoup les opérations de modification des données. Nous n'avons pas besoin de changer l'index, nous avons juste besoin de changer les valeurs sur la feuille de l'arbre. C'est pourquoi même un changement massif du champ Age n'aura pas un grand impact sur les performances. Cela affectera certainement, mais pas tellement.

Autant que je sache, les valeurs de l'index clusterisé sont automatiquement incluses dans le niveau feuille, mais cela doit être vérifié avec la spécification.

Alors, quand l'utilisation des champs inclus est-elle bénéfique ? Lorsqu'ils sont fréquemment utilisés dans les résultats de requête, mais qu'ils sont modifiés de temps à autre. Un exemple est un tableau de transactions bancaires. Ce tableau peut comprendre les champs suivants :numéro de compte, type de transaction, date, somme. Il ne sert à rien d'indexer par la somme, mais nous pouvons l'inclure dans l'index et cela accélérera considérablement la requête.

Pour récupérer l'effet réel de l'indexation, les requêtes ne doivent pas sélectionner tous les champs, c'est-à-dire qu'il faut oublier la table SELECT * FROM. Ne recalculez toujours que les champs dont vous avez vraiment besoin. Et si leurs valeurs finissent par figurer dans l'index, la vitesse d'exécution peut être assez élevée.

Outil utile :

dbForge Index Manager - complément SSMS pratique pour analyser l'état des index SQL et résoudre les problèmes de fragmentation d'index.