web-dev-qa-db-fra.com

Est-ce une optimisation prématurée pour ajouter des index de base de données?

Un de mes collègues a suggéré aujourd'hui de parcourir toutes les requêtes de notre application et d'ajouter des indices en conséquence.

Je pense que c'est une optimisation prématurée car notre application n'est même pas encore sortie. J'ai suggéré de surveiller les requêtes lentes une fois que nous sommes en ligne, puis d'ajouter des indices en conséquence.

Quel est le consensus général lors de la conception de votre base de données, devez-vous ajouter un index correspondant à chaque fois que vous écrivez une nouvelle requête? Ou est-il préférable de simplement surveiller et voir comment ça se passe?

61
Marco de Jongh

L'optimisation prématurée consiste à "optimiser" quelque chose en raison d'un sentiment vague et intuitif que, vous savez, cela sera probablement lent, surtout au détriment de la lisibilité et de la maintenabilité du code. Cela ne signifie pas volontairement de ne pas suivre les bonnes pratiques bien établies en matière de performances.

Parfois, c'est une ligne difficile à tracer, mais je dirais certainement que ne pas ajouter d'index avant de commencer est optimisation trop tardive; cela punira les utilisateurs précoces - vos utilisateurs les plus désireux et les plus importants - et leur donnera une vision négative de votre produit, qu'ils diffuseront ensuite dans les avis, les discussions, etc. bonne idée, mais je m'assurerais de le faire au plus tard en version bêta.

132
Mason Wheeler

surveiller les requêtes lentes une fois que nous sommes en ligne

car rien ne dit la qualité comme faire souffrir vos utilisateurs par manque de design!

Vous devez savoir quelles requêtes ont besoin d'index lorsque vous concevez les tables, vous savez quelles colonnes sont interrogées dans les clauses where et les jointures. Ceux-ci doivent déjà être indexés car ce qui peut ne pas être apparent dans un environnement en direct peut rapidement devenir apparent lorsque la charge ou les données stockées augmentent. Ce que vous ne voulez pas faire lorsque cela se produit, c'est gifler des index sur chaque requête "lente", vous vous retrouverez avec un index sur tout.

48
gbjbaanb

"Optimisation prématurée", dans son sens péjoratif, signifie une optimisation coûteuse qui pourrait ne pas être nécessaire. Cela ne signifie pas signifie toute optimisation mise en œuvre avant le dernier point possible pour éviter la faillite!

En particulier, il est légitime d'optimiser sur la base de tests de performances avant la mise en ligne, pour vous assurer que vous pouvez répondre à certaines exigences raisonnables (bien qu'approximatives) pour que votre application ne suce pas complètement.

Au minimum absol vous devez charger votre base de données avec une quantité plausible de données de test et vérifier la réactivité de votre application. Ce n'est pas prématuré, car vous savez que cela va se produire, et cela interceptera toutes les requêtes qui déclencheront des analyses extrêmement lentes. Comme le dit A E dans un commentaire:

Utilisez des index pour éviter une analyse complète de la table pour toute requête que l'utilisateur final effectuera généralement en temps réel

Au moins, pour les tables dont la croissance est prévue.

Ensuite, en tant que raccourci, si vous avez une expérience significative avec le moteur de base de données et que vous avez déjà planifié les tests lorsque vous écrivez la première coupe du code, alors vous saurez souvent sans même l'exécuter que la requête que vous êtes l'écriture sera trop lente sans index. Bien sûr, vous êtes libre de prétendre que vous ne savez pas et de regarder le test échouer avant d'ajouter l'index pour le faire passer, mais il n'y a aucune raison pour que le code défectueux connu (car ne répondant pas) soit mis en ligne.

26
Steve Jessop

Je pense que c'est une optimisation prématurée car notre application n'est même pas encore sortie. J'ai suggéré de surveiller les requêtes lentes une fois que nous sommes en ligne, puis d'ajouter des indices en conséquence.

Vous ne pouvez pas traiter vos utilisateurs finaux et votre environnement de production comme une assurance qualité. En d'autres termes, vous dites que vous le découvrirez en production. Je ne pense pas que ce soit la bonne façon, et Je vois que cette approche tourne horriblement mal chaque jour.

Vous devez garder une chose à l'esprit, car vous ne pouvez pas peindre cela avec un pinceau large.

Quel est ton charge de travail commune?

Cela peut sembler évident ou terne, mais c'est important dans la pratique. Si vous avez 10 requêtes qui représentent 98% de votre charge de travail (assez courant, croyez-le ou non), ma recommandation serait un analyse approfondie avant la production. Avec des données réalistes et représentatives, assurez-vous que ces 10 requêtes sont aussi bonnes que possible ( parfait est une perte de temps précieux, et presque impossible à réaliser).

Pour les 200 autres requêtes qui constituent les 2% de la charge de travail , ce sont celles qui ne valent probablement pas une tonne d'efforts, et qui composent la perf-coin-case perf dépannage des bizarreries en production. C'est aussi une réalité, et pas une très mauvaise chose. Mais cela ne signifie pas ignorer les meilleures pratiques d'indexation ou faire des hypothèses estimées sur la récupération des données.

Il est courant et de bonne pratique de déterminer les performances de la base de données avant la production. En fait, il existe une position relativement commune pour ce type de chose appelée développement DBA .

Mais...

Certains vont trop loin et deviennent fous en ajoutant des index "au cas où". Quelqu'un recommande que ce soit un index manquant? Ajoutez-le et quatre autres variantes. C'est aussi une mauvaise idée. Vous devez non seulement penser à votre récupération de données, mais qu'en est-il de la modification des données? Plus vous avez d'index sur une table, en général, plus vous avez de surcharge lorsque vous modifiez des données.

Comme la plupart des choses, l'équilibre est sain.

Comme une petite note amusante ... La pluralisation de "Index"

"Les indices" sont pour les financiers

"Les index" sont pour nous

20
Thomas Stringer

Non, ce n'est pas une optimisation prématurée, mais cela doit être fait correctement comme toute optimisation devrait l'être.

Voici ce que je ferais:

  1. Chargez la base de données avec suffisamment de données de test pour imiter une charge de production. Vous ne pouvez pas obtenir cette précision à 100%, mais c'est très bien: insérez simplement suffisamment de données. Une table contient-elle une quantité fixe de données? Chargez-le. Avez-vous une table qui contient beaucoup de données, par exemple quelle table contient des questions sur ce site? Chargez quelques millions d'enregistrements même s'il ne s'agit que de données factices.
  2. Activer le profilage dans votre serveur de base de données.
  3. Frappez l'application en utilisant une combinaison de scripts automatisés (fournit du volume) et de vrais utilisateurs (ils savent casser les choses).
  4. Passez en revue les données de profilage. Les requêtes spécifiques sont-elles lentes? Vérifiez les plans d'explication et voyez si le serveur de base de données vous dit qu'il veut un index mais qu'il n'existe pas.

Les serveurs de bases de données sont des logiciels complexes et intelligents. Ils peuvent vous dire comment les optimiser si vous savez écouter.

Les clés sont mesure les performances avant et après l'optimisation et et laissez la base de données vous dire ce dont elle a besoin.

4
user22815

Suivre des modèles éprouvés pour des problèmes connus (comme trouver un enregistrement par son ID) n'est rien de prématuré. C'est juste raisonnable.

Cela dit, les indices ne sont pas toujours une affaire simple. Il est souvent difficile de savoir pendant la phase de conception de quels index dépendra votre trafic et qui goulot d'étranglement des opérations d'écriture. Donc, je plaiderais pour tirer parti de certaines des meilleures pratiques de conception de schéma "évidentes" (utilisez les PK appropriés pour les modèles de lecture/écriture et les FK d'indexation conçus); mais, ne mettez pas d'index sur autre chose jusqu'à ce que votre test de résistance l'exige.

3
svidgen

Lorsque votre application est publiée, il est trop tard.

Mais tout processus de développement approprié doit inclure des tests de performances.

Utilisez les résultats de vos tests de performances pour décider quels index ajouter et vérifiez leur efficacité en répétant les tests de performances.

2
Philipp

Bien que je ne pense pas que chaque requête devrait être optimisée, les index font tellement partie du SGBDR qu'ils doivent être pris en considération avant d'être publiés. Lorsque vous exécutez une requête, contrairement à d'autres formes de programmation, vous ne dites pas au système comment l'exécuter. Ils élaborent leurs propres plans et les fondent presque toujours sur la disponibilité d'un indice. La composition et le volume des données seront également pris en compte ultérieurement.

Voici certaines choses que je considérerais:

  1. Il y a certaines requêtes que vous devez identifier au début de votre développement et dont vous savez qu'elles seront utilisées fréquemment. Concentrez-vous sur eux.
  2. Il y aura des requêtes lentes. En les indexant d'abord, vous pouvez ensuite déterminer si les performances ne sont toujours pas assez rapides, puis envisager une refonte (la dénormalisation peut être prématurée). Je préfère le faire avant une sortie. Personne ne veut un système où il faut 10 minutes pour trouver quelque chose dans l'inventaire.
  3. Les index peuvent améliorer les performances des requêtes, mais ils ne doivent pas entraver la modification des données.
  4. De nombreux systèmes disposent d'outils pour analyser vos requêtes, alors n'ayez pas peur de les utiliser.

Après votre examen initial, vous devriez faire un suivi avec quelques considérations pour savoir quand vous devriez le réexaminer et comment vous allez pouvoir collecter les informations pour ce faire (surveiller l'utilisation, obtenir des copies des données client, etc.).

Je me rends compte que vous ne voulez pas optimiser prématurément, mais il est presque certain que vous aurez de mauvaises performances sans indexer votre base de données. En éliminant cela, vous pouvez déterminer s'il existe d'autres domaines à l'origine de problèmes de performances.

1
JeffO

Il est recommandé d'identifier les colonnes qui ont définitivement besoin d'un index par une analyse initiale. Il existe un risque réel de dégradation progressive ou inattendue des performances de production à mesure que la taille de la base de données augmente si vous n'avez absolument aucun indice. La situation que vous souhaitez éviter est celle où une requête couramment exécutée nécessite l'analyse d'un grand nombre de lignes de table. Il n'est pas prématuré d'optimiser l'ajout d'indices aux colonnes critiques, car vous disposez de la plupart des informations nécessaires et les différences de performances potentielles sont importantes (ordres de grandeur). Il y a aussi des situations où l'avantage des indices est moins clair ou plus dépendant des données - vous pouvez probablement différer la décision pour certains de ces cas.

Certaines questions que vous devez vous poser sont:

  • Quelles seront les limites de conception pour la taille de chaque table?

Si les tables vont toujours être petites (disons <100 lignes), ce n'est pas un désastre si la base de données doit analyser la table entière. Il peut être avantageux d'ajouter un indice, mais cela nécessite un peu plus d'expertise ou de mesure pour le déterminer.

  • À quelle fréquence chaque requête sera-t-elle exécutée et quel est le temps de réponse requis?

Si la requête est exécutée peu fréquemment et n'a pas d'exigences de temps de réponse strictes (par exemple, la génération de rapports) et que le nombre de lignes n'est pas énorme, il est probablement assez sûr de différer l'ajout d'index. Encore une fois, l'expertise ou la mesure peuvent aider à savoir si cela va être bénéfique.

  • La requête nécessite-t-elle de rechercher la table en dehors de la clé primaire? Par exemple. filtrage par plage de dates, connexion sur une clé étrangère?

Si ces requêtes sont exécutées fréquemment et touchent des tables avec de nombreuses lignes, vous devez sérieusement envisager d'ajouter un index de manière préventive. Si vous n'êtes pas sûr que ce soit le cas pour une requête, vous pouvez remplir la base de données avec une quantité réaliste de données, puis consulter le plan de requête.

0
user611910

Cela dépend également du nombre d'utilisateurs que vous attendez. Vous devriez certainement faire des tests de charge et vous assurer que votre base de données peut suivre 10 à 100 à 1 000 requêtes simultanées. Encore une fois, cela dépend de la quantité de trafic que vous attendez et des zones que vous prévoyez d'utiliser plus que d'autres.

En général, je voudrais affiner les zones que j'attends de l'utilisateur en premier. Ensuite, je peaufinerais tout ce qui est lent du point de vue de l'expérience utilisateur. Chaque fois que l'utilisateur doit attendre quelque chose, il obtient une mauvaise expérience et peut être refusé. Pas bon!

0
harsimranb