par Guillaume Lelarge.

Insertion


Le nombre d'index sur une table est le facteur le plus important pour les performances d'un insert. Plus une table a d'index, plus l'exécution sera lente. L'instruction insert est la seule opération qui ne peut pas bénéficier directement de l'indexation car elle n'a pas de clause where.

Ajouter une nouvelle ligne dans une table implique de suivre plusieurs étapes. Tout d'abord, la base de données doit trouver une place pour enregistrer la ligne. Pour une table standard, sans ordre particulier pour les lignes, la base de données peut utiliser tout bloc de la table qui dispose de suffisamment d'espace libre. C'est un traitement très simple et très rapide, généralement exécuté en mémoire. Tout ce qui reste à faire est d'ajouter la nouvelle entrée dans le bloc de données respectif.

Si la table dispose d'index, la base de données doit s'assurer que la nouvelle entrée se trouve dans les index. Pour cela, il doit ajouter la nouvelle entrée dans chaque index de la table. Le nombre d'index est donc un multiplicateur du coût pour une requête insert.

De plus, l'ajout d'une entrée dans un index est bien plus coûteux que son ajout dans une structure de table car la base de données doit conserver l'ordre de l'index et la propriété balancée de l'arbre. La nouvelle entrée ne peut donc pas être écrite dans n'importe quel bloc. Elle appartient à un nœud feuille spécifique. Bien que la base de données utilise l'arbre de l'index pour trouver le bon nœud feuille, elle doit toujours lire quelques blocs d'index pour parcourir l'arbre.

Une fois que le nœud feuille valide a été identifié, la base de données vérifie s'il reste suffisamment de place libre dans ce nœud. Si ce n'est pas le cas, la base de données doit diviser en deux le nœud feuille et distribuer les entrées entre l'ancien nœud et le nouveau nœud. Ce traitement affecte aussi la référence dans le nœud branche correspondant. Il se peut aussi que le nœud branche n'ait plus d'espace, auquel cas il devra être divisé en deux. Dans le pire des cas, la base de données doit diviser tous les nœuds jusqu'au nœud racine. Dans ce seul cas, l'arbre dispose d'une couche supplémentaire, autrement dit sa profondeur grossit.

Il découle de tout cela que la maintenance de l'index est la partie la plus coûteuse de l'instruction insert. C'est aussi visible dans la Figure 8.1, « Performance des insertions suivant le nombre d'index » : le temps d'exécution est difficilement visible si la table n'a pas d'index mais ajouter un seul index est suffisant pour multiplier le temps d'exécution par 100. Et chaque index supplémentaire ralentit encore plus l'exécution.

Figure 8.1 Performance des insertions suivant le nombre d'index

Remarque

La plus grosse différence est observée dès le premier index.

Pour optimiser les performances des insert, il est tout particulièrement important d'avoir un nombre d'index le plus petit possible.

Astuce

Utilisez les index délibérément et uniquement s'ils sont nécessaires. Évitez les index redondants autant que possible. Ce sera aussi bénéfique pour les requêtes delete et update.

En ne considérant que les requêtes insert, il serait préférable d'éviter complètement les index. C'est le seul moyen pour obtenir les meilleures performances pour un insert. Néanmoins, des tables sans index sont inimaginables pour les applications. Vous voulez généralement récupérer les données stockées dans la base, donc vous avez besoin d'index pour améliorer les performances des requêtes d'extraction. Même les tables en écriture seule ont souvent une clé primaire, et du coup un index.

Néanmoins, la performance sans les index est si bonne qu'il peut être intéressant de supprimer temporairement tous les index lors du chargement d'une grosse quantité de données, à condition que les index ne soient pas nécessaires pour d'autres requêtes SQL au même moment. Cela peut donner une accélération très importante sur la vitesse d'insertion, à tel point que c'est devenu une pratique courante pour les entrepôts de données.

Réflexion

Quel changement verrait-on sur la Figure 8.1 lors de l'utilisation d'une table organisée en index ou d'un index regroupé ?

Y a-t-il un moyen indirect pour qu'un insert puisse bénéficier d'un index ? autrement dit, comment un index supplémentaire pourrait améliorer les performances d'une requête insert ?

À propos de l'auteur

Photo de Markus Winand

Markus Winand teaches efficient SQL—inhouse and online. He minimizes the development time using modern SQL and optimizes the runtime with smart indexing—for that he also published the book SQL Performance Explained.

Livre de Markus

Couverture du livre « SQL : Au cœur des performances »

L'essence de SQL tuning dans 200 pages.

Acheter de Markus
(Livre de poche et PDF)

Achetez chez Amazon
(Seulement en poche)

“Use The Index, Luke!” by Markus Winand and translated by Guillaume Lelarge is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
Mentions légales | Contact | NO WARRANTY | Marque déposée | Privacy | CC-BY-NC-ND 3.0 license