web-dev-qa-db-fra.com

Meilleures pratiques à suivre avec les index de base de données

Quels sont certains DO et DONT pour améliorer les performances de la base de données à l'aide de l'index?

Un DO serait un cas dans lequel un index devrait être créé, ou une autre astuce liée aux index qui améliorerait les performances.

Un DONT sera un cas où un index ne devrait pas être créé, ou une autre action liée à l'index qui peut nuire aux performances.

17
Click Upvote

Cela dépend en partie de l'utilisation de la base de données, car en général, les index ralentissent les insertions et les mises à jour et accélèrent les requêtes. Dans un entrepôt de données, il n'y a généralement pas de mises à jour et d'insertions par lots, ce qui facilite la création d'index, et beaucoup, beaucoup de requêtes, qui s'accélèrent avec beaucoup d'index. Dans une base de données en ligne pour les ventes sur le Web et autres, il y a beaucoup d'insertions et de mises à jour, donc avoir plus de quelques index soigneusement sélectionnés ne fera que ralentir.

Si vous obtenez un grand nombre de requêtes d'un type spécifique, vous pouvez créer un index pour la requête, bien que ce soit plus pour le traitement en ligne que pour les entrepôts de données. Si certaines colonnes apparaissent souvent dans les requêtes, vous souhaiterez peut-être un index sur cette colonne, ce qui est particulièrement utile pour les entrepôts de données, qui sont interrogés de nombreuses manières différentes et souvent imprévisibles.

Chaque fois que vous ajoutez ou supprimez un index, essayez de faire un test de performances pour voir son effet. Sans cela, vous tirez à l'aveugle.

Il existe des livres sur le réglage des requêtes et des bases de données, souvent spécifiques à un système de base de données et utilisant les outils de ce SGBDR. Cependant, si vous avez besoin d'optimiser la base de données, vous exécutez une opération de grande envergure et vous devriez probablement embaucher un administrateur de base de données avec l'expertise appropriée.

15
David Thornley

Cela dépend fortement de la façon dont vous utilisez vos tables. Il n'y a pas de réponse simple et simple.

Le meilleur conseil que je puisse vous donner est: utiliser un conseiller en réglage . Ils analyseront les commandes de la base de données pendant que vous utilisez l'application, puis effectueront des tests de charge par rapport à celle-ci pour vous fournir des conseils utiles.

Ils existent pour SQL Server & Oracle . Je ne sais pas si d'autres SGBD en ont, mais je doute qu'ils ne fournissent pas de tels outils de base.

Quelques recommandations aléatoires:

  • Les index offrent des gains de performances élevés lorsqu'ils sont appliqués sur des colonnes souvent incluses dans la clause WHERE
  • Utilisez l'index cluster pour la colonne la plus utilisée dans vos requêtes.
  • N'oubliez pas que vous pouvez créer plusieurs index avec une combinaison de colonnes (car elles sont utilisées dans vos requêtes)
  • Avoir de nombreux index diminuera les performances des commandes INSERT.

Dernier conseil: si les performances DB sont vraiment importantes pour votre projet, faites appel à un spécialiste. C'est ce que j'ai fait.

17
user2567

@Pierre 303 l'a déjà dit, mais je le redis. DO utilise des index sur les combinaisons de colonnes. Un indice combiné sur (a, b) n'est que légèrement plus lent pour les requêtes sur a que pour un index sur a seul, et est considérablement meilleur si votre requête combine les deux colonnes. Certaines bases de données peuvent joindre des index sur a et b avant de frapper la table, mais ce n'est pas aussi bon que d'avoir un index combiné. Lorsque vous créez un index combiné, vous devez placer la colonne la plus susceptible d'être recherchée en premier dans l'index combiné.

Si votre base de données le prend en charge, [~ # ~] [~ # ~] place des index sur les fonctions qui apparaissent dans les requêtes plutôt que dans les colonnes. (Si vous appelez une fonction sur une colonne, les index de cette colonne sont inutiles.)

Si vous utilisez une base de données avec de vraies tables temporaires que vous pouvez créer et détruire à la volée (par exemple PostgreSQL, MySQL, mais pas Oracle), alors FAITES créez des index sur des tables temporaires.

Si vous utilisez une base de données qui le permet (par exemple Oracle), FAITES verrouillez les bons plans de requête. Les optimiseurs de requête au fil du temps modifieront les plans de requête. Ils améliorent généralement le plan. Mais parfois, ils aggravent considérablement les choses. Vous ne remarquerez généralement pas vraiment les améliorations du plan - la requête n'était pas un goulot d'étranglement. Mais un seul mauvais plan peut détruire un site très fréquenté.

NE PAS avoir des index sur les tables sur lesquelles vous êtes sur le point d'effectuer un chargement de données important. Il est beaucoup, beaucoup plus rapide de supprimer des index, de charger les données, puis de reconstruire les index que de les maintenir lors du chargement de la table.

DON'T utilisez des index sur les requêtes qui doivent accéder à plus d'une petite fraction d'une grande table. (La taille dépend du matériel. 5% est une règle de base décente.) Par exemple, si vous avez des données avec des noms et un sexe, les noms sont un bon candidat pour l'indexation, car tout nom donné représente une petite fraction du nombre total de lignes. Il ne serait pas utile d'indexer le sexe, car vous devrez toujours accéder à 50% des lignes. Vous voulez vraiment utiliser une analyse complète de la table à la place. La raison en est que les index finissent par accéder à un fichier volumineux de manière aléatoire, ce qui vous oblige à rechercher des disques. Les recherches de disque sont lentes. À titre d'exemple, j'ai récemment réussi à accélérer une requête d'une heure qui ressemblait à:

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

à moins de 3 minutes en le réécrivant comme suit:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

ce qui a forcé la base de données à comprendre qu'elle ne devrait pas essayer d'utiliser l'index tentant sur big_table.small_table_id. (Une bonne base de données, comme Oracle, devrait le comprendre par elle-même. Cette requête s'exécutait sur MySQL.)

pdate: Voici une explication du point de recherche de disque que j'ai fait. Un index donne une recherche rapide pour dire où se trouvent les données dans le tableau. C'est généralement une victoire puisque vous ne regarderez que les données dont vous avez besoin. Mais pas toujours, surtout si vous finirez par consulter un grand nombre de données. Les disques diffusent bien les données, mais ralentissent les recherches. Une recherche aléatoire de données sur disque prend 1/200e de seconde. La version lente de la requête a fini par en faire quelque chose comme 600 000 et a pris près d'une heure. (Il a fait plus de recherches que cela, mais la mise en cache a attrapé certaines d'entre elles.) En revanche, la version rapide savait qu'elle devait tout lire et diffuser des données à quelque chose comme 70 Mo/seconde. Il a traversé une table de 11 Go en moins de 3 minutes.

4
btilly

Fondamentalement, les indices accélèrent la recherche mais ralentissent l'écriture et prennent de la place. C'est le compromis à faire.

Tout champ fréquemment utilisé pour se joindre à, rechercher/comparer sur ou commander par est un candidat pour un index. Pour le savoir, c'est vraiment bénéfique, mesurez. Cependant, les clés étrangères des tables fortement jointes avec beaucoup (> 1000) d'enregistrements et peu d'inserts seront payantes.

Pour les champs de texte, vous pouvez indexer sur une partie du champ (par exemple, les 6 premiers caractères), ce qui accélérerait votre requête mais allégerait la charge sur les index. Les recherches en texte intégral (recherche sur like %substring%) Nécessitent différentes techniques, que je ne connais pas, donc je ne peux pas vous conseiller là-dessus.

Une situation importante où les indices ne vont pas aider: vous ne pouvez pas utiliser l'index des champs de date ou de date/heure complets lorsque vous recherchez (/ join/order) sur une partie de la date. Un index sur date_created Ne vous aidera pas avec une requête comme select * from t where year(date_created) = 2011. Dans mysql, vous ne pouvez pas créer d'index sur une partie de la date. (Lorsque vous utilisez 'between' plutôt que year(), il peut utiliser l'index du champ de date.)

Plus d'informations sur MYSQL dans le manuel: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html

2
Inca

ACTION: Indexez les très rares champs auxquels vous accédez le plus par le biais de requêtes et/ou de comparaisons.

À NE PAS FAIRE: indexez chaque champ de la table en pensant que cela le rendra plus rapide.

Je n'ai pas de statistiques à ce sujet, mais j'essaie de ne pas garder plus de 4 champs indexés dans une table si je peux l'aider. Normaliser mes bases de données aide généralement à garder ces chiffres bas car tout devient consultable par clé numérique (ce qui est plus rapide de toute façon). J'essaie de rester à l'écart des champs de texte intégral pour l'indexation. Ils sont assez lourds.

2
Joel Etherton

ACTION: Essayez de limiter au minimum la taille totale de l'index clusterisé. Les entrées d'index cluster seront incluses dans d'autres index non cluster et à partir de là, il y a un potentiel de gaspillage d'espace disque.

1
user8685

Considérez une table comme un lexique, où les articles sont triés par ordre d'apparition (ou sans ordre utile du tout), et un index de table comme un index de livre pour ce lexique.

Vous utilisez un index pour trouver rapidement quelque chose dans un livre. Au lieu de numériser tout le livre, il vous suffit de trouver la clé dans l'index (un index généralement trié d'une manière ou d'une autre (par catégorie, par domaine scientifique, par époque historique, etc.), cela signifie également que vous n'aurez pas à numériser l'index entier), puis passez à la page de droite.

Contrairement à un livre cependant, un tableau n'est pas une fois imprimé puis immuable. Il est mis à jour tout le temps, et donc chaque index doit être mis à jour avec lui. Bien sûr, cela a un coût d'espace et de temps, qui ne peut être justifié que par l'utilité d'un indice.

Utilisez donc un index pour une colonne, si cette colonne est utilisée comme clé dans les requêtes de recherche fréquentes, et n'en utilisez pas, sinon. Le mot fréquent est aussi bon quantificateur que possible, en général. En fin de compte, vous devrez faire une bonne estimation de celles qui sont fréquentes, puis simplement comparer les performances avec ou sans indice en cas de doute.

1
back2dos