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

17

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.

Cliquez Upvote
la source
3
profile, profile, profile
GrandmasterB

Réponses:

15

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 sont accélérées 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 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. Si vous avez besoin d'optimiser beaucoup la base de données, cependant, vous exécutez une grande opération et vous devriez probablement embaucher un DBA avec l'expertise appropriée.

David Thornley
la source
17

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: faites appel à un conseiller en tuning . 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 et 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 fournissent 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.


la source
2
+1 pour les index sur les combinaisons de colonnes. Index sur les colonnes aet bn'est pas identique à un index sur (a, b). Ce dernier est presque aussi bon que l'index apour accélérer les requêtes avec une condition a, est massivement mieux pour les requêtes avec conditions aet b, et n'est pas utile pour les requêtes sur la bseule. (La plupart des bases de données ne l'utiliseront pas. Oracle le fera, mais n'en
retirera
2
+1, ajouterait "apprendre à lire les plans de requête pour que vous sachiez quoi indexer"
Steven A. Lowe
4

@Pierre 303 l'a déjà dit, mais je le redis. UTILISEZ les index sur les combinaisons de colonnes. Un index combiné activé (a, b)n'est que légèrement plus lent pour les requêtes activées aqu'un index aseul et est considérablement meilleur si votre requête combine les deux colonnes. Certaines bases de données peuvent joindre des index sur aet bavant d'atteindre 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 prend en charge, DO mettre les index sur les fonctions qui apparaissent dans les requêtes plutôt que des 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), puis NE créer des index sur les tables temporaires.

Si vous utilisez une base de données qui permet (par exemple Oracle), DO verrouillage dans 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 d'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.

N'UTILISEZ PAS les 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 empirique 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.)

Mise à jour: 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.

btilly
la source
Salut, je suis confus par votre exemple. J'aurais pensé que l'utilisation de l'index aurait rendu les choses plus rapides, n'est-ce pas le but des index? Êtes-vous en train de dire que si une requête accédait à> 5% d'une table, alors avoir un index sur la colonne que vous recherchez ralentirait les choses?
Cliquez sur Upvote
@Click Upvote: si une requête accède à plus de 5% (fraction exacte fortement dépendante du matériel et des données) d'une table, il est plus rapide de ne pas utiliser d'index pour cette requête. Avoir un index ne fait pas de mal tant que vous ne l'utilisez pas. Je mettrai à jour avec plus de détails pourquoi.
btilly
Informations utiles. Plus d'informations à ce sujet, par exemple mysqlperformanceblog.com/2007/08/28/… Mais je me demandais, était-ce que «ignorer la clé» n'était pas à la hauteur de ce dont vous avez besoin pour en faire une sous-requête?
Inca
@Inca: Je n'étais pas au courant de "Ignorer la clé". Je change suffisamment de base de données pour qu'il y ait souvent des choses spécifiques à la base de données que je ne connais pas. D'après les sons de celui-ci qui fonctionnerait, mais beaucoup moins efficacement que ma solution éventuelle. La différence étant que cela se joindrait, puis se grouperait, tandis que le mien se grouperait, puis se joindrait. Cela économise du travail sur la jointure car moins d'enregistrements doivent être joints.
btilly
"Une bonne base de données (par exemple Oracle, mais pas MySQL)": veuillez éviter les trucs promotionnels stupides comme ça, surtout lorsque vous ignorez le fait que MySQL peut parfaitement utiliser plusieurs index en même temps (noté "INDEX MERGE" dans les plans de requête) .
Patrick Allaert
2

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.

Joel Etherton
la source
2

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 joindre, rechercher / comparer ou commander par est candidat à 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 effectuez une recherche (/ join / order) sur une partie de la date. Un index sur date_createdne 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' au lieu d' year()utiliser l'index sur le champ de date.)

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

Inca
la source
1

ACTION: Essayez de garder la taille totale de l'index cluster au minimum. 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.


la source
1

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 index de livre de ce lexique.

Vous utilisez un index pour trouver rapidement quelque chose dans un livre. Au lieu de parcourir l'intégralité du livre, il vous suffit de trouver la clé dans l'index (un index étant 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 qu'il obtient, 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.

back2dos
la source