Combien d'index de base de données est trop?


109

Je travaille sur un projet avec une base de données Oracle assez volumineuse (bien que ma question s'applique aussi bien à d'autres bases de données). Nous avons une interface Web qui permet aux utilisateurs de rechercher sur presque toutes les combinaisons possibles de champs.

Pour accélérer ces recherches, nous ajoutons des index aux champs et aux combinaisons de champs sur lesquels nous pensons que les utilisateurs rechercheront généralement. Cependant, comme nous ne savons pas vraiment comment nos clients utiliseront ce logiciel, il est difficile de dire quels index créer.

L'espace n'est pas un problème; nous avons un disque RAID de 4 téraoctets dont nous n'utilisons qu'une petite fraction. Cependant, je m'inquiète des éventuelles pénalités de performances liées à un trop grand nombre d'indices. Étant donné que ces index doivent être mis à jour chaque fois qu'une ligne est ajoutée, supprimée ou modifiée, j'imagine que ce serait une mauvaise idée d'avoir des dizaines d'index sur une seule table.

Alors, combien d'index est considéré comme trop? dix? 25? 50? Ou devrais-je simplement couvrir les cas vraiment, vraiment courants et évidents et ignorer tout le reste?

Réponses:


87

Cela dépend des opérations qui se produisent sur la table.

S'il y a beaucoup de SELECT et très peu de changements, indexez tout ce que vous voulez ... cela accélérera (potentiellement) les instructions SELECT.

Si la table est fortement touchée par les UPDATE, INSERTs + DELETEs ... ceux-ci seront très lents avec beaucoup d'index car ils doivent tous être modifiés à chaque fois qu'une de ces opérations a lieu

Cela dit, vous pouvez clairement ajouter de nombreux index inutiles à une table qui ne feront rien. Ajouter des index B-Tree à une colonne avec 2 valeurs distinctes sera inutile car cela n'ajoute rien en termes de recherche des données. Plus les valeurs d'une colonne sont uniques, plus elle bénéficiera d'un index.


1
Juste pour clarifier, l'index sur 2 valeurs peut ne pas être inutile dans un cas particulier, lorsqu'une valeur arrive rarement et que vous souhaitez la rechercher. Il ne s'agit donc pas de savoir à quel point les valeurs sont uniques, mais à quel point l'indice est sélectif.
charlie_pl

44

Je procède généralement comme ça.

  1. Obtenez un journal des requêtes réelles exécutées sur les données au cours d'une journée typique.
  2. Ajoutez des index pour que les requêtes les plus importantes atteignent les index de leur plan d'exécution.
  3. Essayez d'éviter les champs d'indexation qui ont beaucoup de mises à jour ou d'insertions
  4. Après quelques index, obtenez un nouveau journal et recommencez.

Comme pour toute optimisation, je m'arrête lorsque la performance demandée est atteinte (cela implique évidemment que le point 0. obtiendrait des exigences de performances spécifiques).


26

Tout le monde vous a donné de bons conseils. J'ai une suggestion supplémentaire pour vous à mesure que vous avancez. À un moment donné, vous devez prendre une décision quant à votre meilleure stratégie d'indexation. En fin de compte, la meilleure stratégie d'indexation PLANNED peut encore finir par créer des index qui ne finissent pas par être utilisés. Une stratégie qui vous permet de trouver des index qui ne sont pas utilisés consiste à surveiller l'utilisation des index. Vous procédez comme suit: -

alter index my_index_name monitoring usage;

Vous pouvez ensuite contrôler si l'index est utilisé ou non à partir de ce point en interrogeant v $ object_usage. Vous trouverez des informations à ce sujet dans le manuel Oracle® Database Administrator's Guide .

Rappelez-vous simplement que si vous avez une stratégie d'entreposage consistant à supprimer les index avant de mettre à jour une table, puis à les recréer, vous devrez configurer à nouveau l'index pour la surveillance, et vous perdrez tout historique de surveillance pour cet index.


14

Dans l'entreposage de données, il est très courant d'avoir un nombre élevé d'index. J'ai travaillé avec des tables de faits ayant deux cents colonnes et 190 d'entre elles indexées.

Bien qu'il y ait une surcharge à cela, il doit être compris dans le contexte que dans un entrepôt de données, nous n'insérons généralement une ligne qu'une seule fois, nous ne la mettons jamais à jour, mais elle peut alors participer à des milliers de requêtes SELECT qui pourraient bénéficier de l'indexation sur l'un des Les colonnes.

Pour une flexibilité maximale, un entrepôt de données utilise généralement des index bitmap à colonne unique, sauf sur les colonnes à cardinalité élevée, où des index btree (compressés) peuvent être utilisés.

La surcharge liée à la maintenance des index est principalement associée aux frais d'écriture dans un grand nombre de blocs et le bloc se divise lorsque de nouvelles lignes sont ajoutées avec des valeurs qui sont «au milieu» des plages de valeurs existantes pour cette colonne. Cela peut être atténué en partitionnant et en alignant les nouvelles charges de données sur le schéma de partitionnement et en utilisant des insertions de chemin direct.

Pour répondre à votre question plus directement, je pense qu'il est probablement bien d'indexer l'évidence au début, mais n'ayez pas peur d'ajouter plus d'index pour savoir si les requêtes contre la table en bénéficieraient.


Autant sur un fait? J'aurais deviné que vous étiez sur le point de dire dimension. C'est un cas d'utilisation plutôt bizarre. Mais, vous basculez en tant que DBA alors je vais dire, il me manque évidemment quelque chose.
Stephanie Page

@Stephanie, nous avons à peu près le même scénario. David a mentionné que ce sont des index bitmap. Nous utilisons également les index BITMAP JOIN. Oui, sur des faits. Oracle peut effectuer des opérations AND très efficaces sur les index bitmap. Par exemple, vous pouvez avoir une clause WHERE avec 5 attributs à faible cardinalité dont chacun a un index bitmap. Si vous regardez le plan d'exécution, il aurait un bitmap AND opérations (fondamentalement un bitmap et une opération efficaces), puis dans le plan d'exécution, vous verrez la conversion bitmap en rowids. C'est vraiment rapide.
Tagar

12

Dans une paraphrase d' Einstein sur la simplicité, ajoutez autant d'index que vous en avez besoin et pas plus.

Sérieusement, cependant, chaque index que vous ajoutez nécessite une maintenance chaque fois que des données sont ajoutées à la table. Sur les tables qui sont principalement en lecture seule, de nombreux index sont une bonne chose. Sur les tables très dynamiques, moins c'est mieux.

Mon conseil est de couvrir les cas courants et évidents, puis, lorsque vous rencontrez des problèmes pour lesquels vous avez besoin de plus de vitesse pour obtenir des données à partir de tables spécifiques, évaluez et ajoutez des indices à ce stade.

De plus, c'est une bonne idée de réévaluer vos schémas d'indexation tous les quelques mois, juste pour voir s'il y a quelque chose de nouveau qui nécessite une indexation ou des indices que vous avez créés qui ne servent à rien et devraient être supprimés. .


1
Je suis d'accord sur la réévaluation. Une bonne administration n’est jamais une tâche consistant à «régler et oublier». Modifications du logiciel. Les exigences changent. Changements d'utilisation. Une nouvelle fonctionnalité apparemment insignifiante introduite un jour peut rapidement devenir votre plus gros goulot d'étranglement, et le code de base du pain et du beurre d'hier peut devenir une graisse dormante et inutile qui ne fait que consommer des ressources. Je suis également d'accord avec une approche itérative. Si vous en faites trop à la fois, vous ne saurez pas ce qui a fonctionné.
durette

6

En plus des points que tout le monde a soulevés, l'Optimiseur basé sur les coûts entraîne un coût lors de la création d'un plan pour une instruction SQL s'il y a plus d'index car il y a plus de combinaisons à prendre en compte. Vous pouvez réduire ce problème en utilisant correctement des variables de liaison afin que les instructions SQL restent dans le cache SQL. Oracle peut alors effectuer une analyse logicielle et réutiliser le plan qu'il a trouvé la dernière fois.

Comme toujours, rien n'est simple. S'il y a des colonnes et des histogrammes biaisés, cela peut être une mauvaise idée.

Dans nos applications Web, nous avons tendance à limiter les combinaisons de recherches que nous autorisons. Sinon, vous devrez tester littéralement chaque combinaison pour la performance pour vous assurer que vous n'avez pas un problème caché que quelqu'un trouvera un jour. Nous avons également implémenté des limites de ressources pour éviter que cela ne cause des problèmes ailleurs dans l'application en cas de problème.


J'ai voté mais ... Je dirais que le temps d'analyse supplémentaire, bien qu'intéressant et académique, n'influencerait jamais mon choix pour le nombre correct d'index. se mettre d'accord?
Stephanie Page

@StephaniePage Je n'ai pas fait d'expérience pour prouver quoi que ce soit. J'ai cependant vu un projet qui créait naïvement un index à une seule colonne sur chaque colonne. Si certains tableaux ont 80 colonnes, je suppose que cela pourrait commencer à avoir un impact. Oracle semble tenir compte du coût d'accès de chaque index. Mais oui, je suis d'accord, il y a des choses plus importantes à considérer que cela.
WW.

Mmm ... je crois qu'il y a un temps maximum qu'Oracle passera dans une analyse difficile ... considérons un SQL avec plus de quelques tables, disons 7 ou 8, le choix de l'ordre de jointure à lui seul pourrait générer des centaines de chemins d'accès.
Stephanie Page

6

J'ai fait quelques tests simples sur mon vrai projet et la vraie base de données MySql. J'ai déjà répondu dans cette rubrique: quel est le coût de l'indexation de plusieurs colonnes db?

Mais je pense que ce sera mieux si je le cite ici:

J'ai fait quelques tests simples en utilisant mon vrai projet et une vraie base de données MySql.

Mes résultats sont: l'ajout d'un index moyen (1 à 3 colonnes dans un index) à une table - ralentit les insertions de 2,1%. Ainsi, si vous ajoutez 20 index, vos insertions seront plus lentes de 40 à 50%. Mais vos sélections seront 10 à 100 fois plus rapides.

Alors est-il correct d'ajouter de nombreux index? - Cela dépend :) Je vous ai donné mes résultats - Vous décidez!


Cela ne devrait pas être considéré comme une prophétie sans tous les détails. Surtout parce que vous ne pouvez pas multiplier les gains / pertes de performances d'une action à une autre. La base reste la même: ajoutez plus d'index et vos insertions seront éventuellement plus lentes à cause de la recréation d'index.
SovietFrontier

3

En fin de compte, le nombre d'index dont vous avez besoin dépend du comportement de vos applications qui chevauchent votre serveur de base de données.

En général, plus vous insérez, plus vos index deviennent douloureux. Chaque fois que vous effectuez une insertion, tous les index qui incluent cette table doivent être mis à jour.

Maintenant, si votre application a une quantité décente de lecture, ou même plus si elle est presque entièrement en lecture, alors les index sont la voie à suivre car il y aura des améliorations majeures des performances pour très peu de frais.


3

Il n'y a pas de réponse statique à mon avis, ce genre de chose relève du «réglage des performances».

Il se peut que tout ce que fait votre application soit recherché par une clé primaire ou que les requêtes soient effectuées sur des combinaisons illimitées de champs et que n'importe lequel en particulier puisse être utilisé à tout moment.

Au-delà de la simple indexation, il y a reogranisation de votre base de données pour inclure des champs de recherche calculés, des tables de fractionnement, etc. - cela dépend vraiment de vos formes de charge et des paramètres de requête, de la quantité / de quelles données `` vraiment '' doivent être récupérées par une requête.

Si toute votre base de données est confrontée à des façades de procédure stockée, le tournage devient un peu plus facile, car vous n'avez pas à vous soucier de chaque requête ad hoc. Ou vous pouvez avoir une compréhension approfondie du type de requêtes qui toucheront votre base de données, et pouvez limiter le réglage à celles-ci.

Pour SQL Server, j'ai trouvé le conseiller de réglage du moteur de base de données utile - vous configurez des charges de travail `` typiques '' et il peut faire des recommandations sur l'ajout / la suppression d'index et de statistiques. Je suis sûr que d'autres bases de données ont des outils similaires, qu'ils soient «officiels» ou tiers.


3

C'est vraiment une question plus théorique que pratique. L'impact des index sur vos performances dépend du matériel dont vous disposez, de la version d'Oracle, des types d'index, etc. Hier, j'ai entendu qu'Oracle avait annoncé un stockage dédié, fabriqué par HP, qui est censé fonctionner 10 fois plus vite avec une base de données 11g. Quant à votre cas, il peut y avoir plusieurs solutions: 1. Avoir une grande quantité d'index (> 20) et les reconstruire quotidiennement (tous les soirs). Cela serait particulièrement utile si la table reçoit des milliers de mises à jour / suppressions par jour. 2. Partitionnez votre table (si cela s'applique à votre modèle de données). 3. Utilisez une table distincte pour les données nouvelles / mises à jour et exécutez un processus nocturne qui combine les données ensemble. Cela nécessiterait une modification de la logique de votre application. 4. Basculez vers IOT (table organisée par index), si vos données le prennent en charge.

Bien sûr, il pourrait y avoir beaucoup plus de solutions pour un tel cas. Ma première suggestion serait de cloner la base de données dans un environnement de développement et d'exécuter des tests de résistance contre elle.


Je ne comprends pas comment la reconstruction des index aiderait, ou comment un IOT aiderait.
David Aldridge le

IOT - s'il est possible de reconcevoir l'application, de sorte qu'un nouveau type de données défini par l'utilisateur soit utilisé, alors l'IOT économiserait la surcharge liée à l'indexation de la table. ce n'est peut-être pas le cas ici. cela dépend vraiment. reconstruction de l'index - au cas où il y aurait de nombreux index et que les nouvelles données ne seraient pas indexées.
Moshe le

Un IOT est toujours une structure d'index, avec plus de surcharge sur les fractionnements de blocs qu'un index normal. "reconstruction de l'index - au cas où il y aurait beaucoup d'index et que de nouvelles données ne seraient pas indexées" ... de quel SGBDR parlez-vous qui ne maintient pas automatiquement les index pour les nouvelles entrées?
David Aldridge

David - vous avez raison bien sûr. J'ai mélangé cela avec la capacité de SQL Server d'indexer la recherche de texte intégral uniquement à la demande. J'aurais aimé que Oracle l'ait, car cela pourrait être utile dans ce cas. Je recommanderais de m'en tenir aux deux autres suggestions.
Moshe le

2

Si vous effectuez principalement des lectures (et peu de mises à jour), il n'y a vraiment aucune raison de ne pas indexer tout ce dont vous aurez besoin pour indexer. Si vous mettez souvent à jour, vous devrez peut-être être prudent sur le nombre d'index dont vous disposez. Il n'y a pas de chiffre précis, mais vous remarquerez quand les choses commencent à ralentir. Assurez-vous que votre index clusterisé est celui qui a le plus de sens en fonction des données.


2

Vous pouvez envisager de créer des index pour cibler une combinaison standard de recherches. Si la recherche de colonne1 est courante, et que la colonne2 est souvent utilisée avec elle, et que la colonne3 est parfois utilisée avec la colonne2 et la colonne1, alors un index sur colonne1, colonne2 et colonne3 dans cet ordre peut être utilisé pour l'une de ces trois circonstances, bien qu'il soit un seul index à maintenir.


2

Un index impose un coût lorsque la table sous-jacente est mise à jour. Un index offre un avantage lorsqu'il est utilisé pour rédiger une requête. Pour chaque indice, vous devez équilibrer le coût et l'avantage. Dans quelle mesure la requête s'exécute-t-elle plus lentement sans l'index? Dans quelle mesure un avantage est-il plus rapide? Pouvez-vous ou vos utilisateurs tolérer la vitesse lente lorsque l'index est manquant?

Pouvez-vous tolérer le temps supplémentaire nécessaire pour effectuer une mise à jour?

Vous devez comparer les coûts et les avantages. C'est particulier à votre situation. Il n'y a pas de nombre magique d'index qui dépasse le seuil de «trop».

Il y a aussi le coût de l'espace nécessaire pour stocker l'index, mais vous avez dit que dans votre situation, ce n'est pas un problème. Il en va de même dans la plupart des situations, étant donné le faible coût de l’espace disque.


1

Combien de colonnes y a-t-il? On m'a toujours dit de créer des index à une seule colonne, pas des index à plusieurs colonnes. Donc pas plus d'index que le nombre de colonnes, à mon humble avis.


1

Il s'agit en fait de ne pas ajouter d'index à moins que vous ne sachiez (et cela signifie souvent la collecte de statistiques d'utilisation) qu'il sera utilisé beaucoup plus souvent qu'il n'est mis à jour.

Tout index qui ne répond pas à ces critères vous coûtera plus cher à reconstruire que la pénalité de performance de ne pas l'avoir dans le cas étrange où il a été utilisé.


1

Le serveur SQL vous offre de bons outils qui vous permettent de voir quels index sont réellement utilisés. Cet article, http://www.mssqltips.com/tip.asp?tip=1239 , vous donne quelques requêtes qui vous permettent de mieux comprendre combien un index est utilisé, par opposition à combien il est mis à jour.


0

Il est totalement basé sur les colonnes qui sont utilisées dans la clause Where. Et comme le pouce de la règle, nous devons avoir des index sur les colonnes de clé étrangère pour éviter les DEADLOCKS. Le rapport AWR doit être analysé périodiquement pour comprendre le besoin d'index.


2
Index sur les colonnes de clé étrangère pour éviter les blocages? Avez-vous une référence qui explique pourquoi et comment c'est le cas?
Jay Sullivan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.