Je travaille sur un projet avec une base de données Oracle assez volumineuse (bien que ma question s'applique également aux 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 des combinaisons de champs sur lesquels nous pensons que les utilisateurs effectueront généralement des recherches. 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 une préoccupation; 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'index. Parce 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?
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 aimez .... ceux-ci accélèreront (potentiellement) les instructions SELECT.
Si la table est fortement touchée par les MISES À JOUR, INSÉRER + SUPPRIMER ... celles-ci seront très lentes avec beaucoup d'index car elles doivent toutes être modifiées à chaque fois qu'une de ces opérations a lieu
Cela dit, vous pouvez clairement ajouter un grand nombre d'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.
Je procède habituellement comme ça.
Comme pour toute optimisation, je m'arrête lorsque les performances demandées sont atteintes (cela implique évidemment que le point 0 obtiendrait des exigences de performances spécifiques).
Tout le monde vous a donné d'excellents 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 cependant, la meilleure stratégie d'indexation PLANIFIÉE 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 moment en interrogeant v $ object_usage. Vous trouverez des informations à ce sujet dans le Oracle® Database Administrator's Guide .
N'oubliez pas que si vous avez une stratégie d'entreposage consistant à supprimer des 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.
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 un surcoût à cela, il faut comprendre dans le contexte que dans un entrepôt de données, nous n'insérons généralement qu'une ligne une fois, nous ne la mettons jamais à jour, mais elle peut ensuite 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.
Les frais généraux liés à la maintenance des index sont principalement associés aux frais d'écriture sur un grand nombre de blocs et les blocs se divisent à mesure que 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 plus directement à votre question, je pense qu'il est probablement correct d'indexer l'évidence au début, mais n'ayez pas peur d'ajouter plus d'index si les requêtes sur la table en bénéficieraient.
Dans une paraphrase de 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 des 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 où vous avez besoin de plus de vitesse pour obtenir des données à partir de tables spécifiques, d'évaluer et d'ajouter 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 a besoin d'indexation ou des index que vous avez créés qui ne sont utilisés pour rien et devraient être supprimés .
J'ai fait quelques tests simples sur mon vrai projet et ma 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 ma vraie base de données MySql.
Mes résultats sont les suivants: ajouter un indice moyen (1 à 3 colonnes dans un index) à une table - ralentit les insertions de 2,1%. Donc, si vous ajoutez 20 index, vos insertions seront plus lentes de 40 à 50%. Mais vos sélections seront 10 à 100 fois plus rapides.
Est-il donc correct d'ajouter de nombreux index? - Ça dépend :) Je vous ai donné mes résultats - Vous décidez!
En plus des points soulevés par tous les autres, 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 cela en utilisant correctement les variables de liaison afin que les instructions SQL restent dans le cache SQL. Oracle peut ensuite effectuer une analyse souple et réutiliser le plan trouvé la dernière fois.
Comme toujours, rien n'est simple. S'il y a des colonnes asymétriques et des histogrammes impliqué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 toutes les combinaisons de performances pour vous assurer que vous n'avez pas eu de problème caché que quelqu'un trouvera un jour. Nous avons également mis en place des limites de ressources pour éviter que cela ne cause des problèmes ailleurs dans l'application en cas de problème.
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 plus encore si c'est presque toute la lecture, alors les index sont la voie à suivre car il y aura des améliorations de performances majeures pour très peu de coûts.
Il n'y a pas de réponse statique à mon avis, ce genre de chose relève du "réglage des performances".
Il se pourrait que tout ce que fait votre application soit recherché par une clé primaire, ou cela pourrait être l'opposé dans la mesure où les requêtes sont effectuées sur des combinaisons non restreintes de champs et n'importe lequel en particulier pourrait être utilisé à un moment donné.
Au-delà de l'indexation, il y a une réorganisation de votre base de données pour inclure des champs de recherche calculés, des tables de fractionnement, etc.
Si toute votre base de données est confrontée à des façades de procédures stockées, 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 d'optimisation 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.
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. 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 le tableau reçoit quotidiennement des milliers de mises à jour/suppressions. 2. Partitionnez votre table (si cela s'applique à votre modèle de données). 3. Utilisez un tableau séparé pour les données nouvelles/mises à jour et exécutez un processus nocturne qui combine les données ensemble. Cela nécessiterait un changement dans la logique de votre application. 4. Passez à 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 celui-ci.
Si vous effectuez principalement des lectures (et quelques mises à jour), il n'y a vraiment aucune raison de ne pas indexer tout ce dont vous aurez besoin pour indexer. Si vous mettez à jour souvent, vous devrez peut-être faire attention au nombre d'index dont vous disposez. Il n'y a pas de chiffre fixe, mais vous remarquerez quand les choses commenceront à ralentir. Assurez-vous que votre index cluster est celui qui a le plus de sens en fonction des données.
Vous pouvez envisager de créer des index pour cibler une combinaison standard de recherches. Si la colonne1 est couramment recherchée, 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 la colonne1, la colonne2 et la colonne3 dans cet ordre peut être utilisé pour n'importe laquelle de ces trois circonstances, bien qu'il soit un seul index qui doit être maintenu.
Un index impose un coût lorsque la table sous-jacente est mise à jour. Un index offre un avantage lorsqu'il est utilisé pour compléter une requête. Pour chaque indice, vous devez équilibrer le coût et l'avantage. Combien de temps la requête s'exécute-t-elle 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 terminer une mise à jour?
Vous devez comparer les coûts et les avantages. Cela 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, compte tenu de la rareté de l'espace disque.
Le serveur SQL vous donne 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 d'avoir une meilleure idée de la façon dont un index est utilisé, par opposition à combien il est mis à jour.
Combien de colonnes y a-t-il? On m'a toujours dit de faire des index à une seule colonne, pas des index à plusieurs colonnes. Donc pas plus d'index que le nombre de colonnes, à mon humble avis.
Ce qui se résume vraiment à, n'ajoutez pas d'index à moins que vous ne sachiez (et cela signifie souvent recueillir des 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é.
Il est totalement basé sur les colonnes utilisées dans la clause Where. Et en tant que Thumb of Rule, nous devons avoir des index sur les colonnes de clé étrangère pour éviter les DEADLOCKS. Le rapport AWR doit analyser périodiquement pour comprendre le besoin d'index.