Indexation dès le début ou lorsqu'un problème de performances survient?

15

Ma question concerne l'utilisation des index.

  1. Dois-je commencer l'indexation dès le début ou lorsqu'un problème de performances survient?

  2. Nous pouvons également créer un index temporaire lors de l'exécution d'une requête. Quels sont les avantages et les inconvénients de telles techniques?

codecool
la source

Réponses:

17

Dois-je commencer l'indexation dès le début ou lorsqu'un problème de performances survient?

La stratégie d'indexation a tendance à évoluer avec l'émergence de modèles d'utilisation. Cela dit, il existe également des stratégies et des lignes directrices de conception qui peuvent être appliquées dès le départ.

  • Choisissez une bonne clé de clustering . Vous pouvez généralement déterminer l'index cluster approprié au moment de la conception, en fonction du modèle attendu d'insertions dans une table. Si un cas convaincant émerge pour un changement dans le futur, qu'il en soit ainsi.

  • Créez vos contraintes principales et autres uniques . Ceux-ci seront appliqués par des index uniques.

  • Créez vos clés étrangères et les index non cluster associés . Les clés étrangères sont vos colonnes de jointure les plus fréquemment référencées, alors indexez-les dès le début.

  • Créez des index pour toute requête manifestement hautement sélective . Pour les modèles de requête que vous connaissez déjà, ils seront très sélectifs et utiliseront probablement des recherches plutôt que des analyses.

Au-delà de ce qui précède, adoptez une approche progressive et holistique pour mettre en œuvre de nouveaux index. Par holistique, j'entends évaluer le bénéfice potentiel et l'impact sur toutes les requêtes et les index existants lors de l'évaluation d'un ajout.

Un problème non rare dans les cercles SQL Server est la sur-indexation, à la suite des conseils des indices DMV et SSMS d'index manquants. Aucun de ces outils n'évalue les index existants et vous proposera joyeusement de créer un nouvel index à 6 colonnes plutôt que d'ajouter une seule colonne à un index à 5 colonnes existant.

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Tripp possède d'excellents documents sur la stratégie d'indexation qui, bien que axée sur SQL, s'applique à d'autres plates-formes. Pour les utilisateurs de SQL Server, il existe des outils pratiques pour identifier les doublons comme l'exemple ci-dessus.

Nous pouvons également créer un index temporaire lors de l'exécution d'une requête. Quels sont les avantages et les inconvénients de telles techniques?

Cela ne s'applique généralement qu'aux requêtes rarement exécutées, généralement ETL. Vous devez évaluer:

  1. Le temps nécessaire pour créer l'index réduit-il le temps d'exécution de la requête?
  2. Est-ce que la surcharge de maintenance de laisser l'index en place l'emporte sur le temps nécessaire pour créer / supprimer lorsque cela est nécessaire.
Mark Storey-Smith
la source
3
+1 Clustering Key, Foreign Key, Unique / Primary Key, et ne pas faire confiance aux DMV d'index manquants à leur valeur nominale ... Toutes ces choses sont d'excellents conseils. La gestion des index existants, dans SQL Server, est assez facile à surveiller à l'aide du DMV sys.dm_db_index_usage_stats. Sur une période de temps, vous pouvez répertorier les index qui n'ont pas été analysés ou recherchés, tout en constatant que ces mêmes index ont été mis à jour plusieurs fois. Cela indique une surindexation.
Matt M
1
+1, cependant, «crée des index pour toute requête manifestement hautement sélective». ne couvre pas tous les autres scénarios. Les index peuvent aider à trier les résultats même si vos requêtes ne sont pas très sélectives. Ils peuvent également accélérer les requêtes si elles couvrent toutes les colonnes sélectionnées.
Unreason
1
D'accord, mais la question cherchait un point de départ plutôt que la fin du match. L'identification des requêtes à couvrir est difficile sans modèles d'utilisation car vous pouvez rarement toutes les couvrir.
Mark Storey-Smith,
8

Il y a vraiment des risques associés aux deux approches:

Option a) Indexez dès le départ, mais ne réalisez pas que vous avez créé un certain nombre d'index qui ne sont jamais utilisés. Celles-ci ajoutent une surcharge (surtout aux requêtes qui modifient les données, mais aussi avec l'optimisation des instructions SELECT essayant d'identifier le meilleur index).

Vous devrez vous discipliner pour identifier les index qui ne sont plus utilisés et essayer de les supprimer (PostgreSQL peut le faire; malheureusement, MySQL par comparaison est très faible à ce stade).

Option b) N'ajoutez pas d'index jusqu'à ce que les gens commencent à se plaindre ou que vos outils de diagnostic déclenchent que certaines requêtes sont lentes et pourraient être améliorées.

Le risque que vous introduisez est que vous n'avez pas une fenêtre de temps suffisamment grande entre le moment où vous remarquez que vous avez besoin de l'index et le moment où vous devez l'ajouter.

PostgreSQL prend en charge la construction d'index CONCURRENTLY, ce qui réduit une partie du stress lié à cette exigence soudaine d'index-ajout, mais certaines mises en garde sont notées dans le manuel.


L'option (b) a tendance à être ma préférence, mais je pense qu'un hybride des deux options est probablement la meilleure solution. Cela a à voir avec votre niveau de confiance quant à savoir si vous pensez qu'un indice sera réellement utilisé.

Ce qui rend cette discussion particulièrement complexe, c'est qu'il est généralement facile de changer les index, mais il est plus difficile de changer de schéma. Je ne veux pas promouvoir la réaction retardée de b comme excuse pour être téméraire.

Morgan Tocker
la source
4

En plus de la réponse de Mark

Vous pouvez vous faire une idée en ayant des données de test réalistes aux quantités attendues. J'ai vu de très nombreux (trop nombreux) cas où une requête s'exécute correctement avec 1000 lignes mais pas le million en production.

Si vous le pouvez, travaillez plus tard sur une copie de la production,

Bien sûr, je n'ai vu le problème étrange qu'en production à cause des modèles d'utilisation lorsque tout le reste est identique

Index temporaires? En dehors des schémas de charge ETL, si vous en avez besoin une fois, vous en aurez à nouveau besoin. N'oubliez pas: un index create / drop est une écriture et est enregistré = plus de charge

gbn
la source
3

Juste pour ajouter quelques petites choses.

  • Les index temporaires sont une idée terrible .. à moins que l'index ne soit sur une table temporaire.
  • Les index occupent beaucoup plus d'espace de données (ainsi que d'autres frais généraux) que les gens ne réalisent. Par conséquent, créez-les de manière conservatrice.

Telle est mon approche.

  1. Semblable à Mark, créez des index là où ils ont du sens, mais ne tardez pas.
  2. Vous n'avez pas à attendre que les performances soient lentes pour créer de nouveaux index. Chaque fois que vous écrivez du nouveau SQL, exécutez un plan de requête (de préférence par rapport à votre base de données prod). Vous devriez pouvoir voir si un nouvel index est requis.
  3. N'ayez pas peur de mettre > 0ou > ""dans vos clauses where pour les colonnes inutilisées.

    1. C'est-à-dire, disons que vous avez un index sur A, B, C et D. Cependant, vous ne disposez que des informations A, B, D. Il n'y a aucune raison pour que vous ne puissiez pas-
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.
user606723
la source
Une autre chose, c'est dans le forum "dba", mais la création d'index devrait vraiment être la responsabilité du développeur, pas celle du dba. (Pour les cas où ils sont complètement séparés.)
user606723
2
Votre déclaration concernant l'espace occupé par les index est un peu trompeuse, il y a très peu de surcharge dans un index non clusterisé. Si vous pouviez poster une question sur ce point, il vaudrait la peine de l'explorer davantage. Deuxièmement, je ne suis pas d'accord pour dire que la création d'index est du domaine du développeur. C'est l'un des domaines où la collaboration entre le développeur et DBA peut donner les meilleurs résultats.
Mark Storey-Smith,
1
Je vais vous donner un exemple d'un de nos tableaux. taille de la table: 21052404 Ko. Taille d'un index non clusterisé sur cette table: 6637470 Ko. Très peu de frais généraux? Je crois que non. De plus, je ne dis pas que les DBA ne devraient pas être collaborés, je dis que ce devrait être la responsabilité du développeur de déterminer si un nouvel index doit être créé. Ils ne devraient pas écrire SQL et s'attendre à ce que le dbas le comprenne par lui-même.
user606723
1
Vous ne pouvez pas citer de tels chiffres sans contexte. Sans spécifier les colonnes d'index NC et la clé en cluster, il est impossible de calculer la proportion de surcharge par rapport aux données.
Mark Storey-Smith,
Touche. La clé est un [numérique (24), caractère, date] et les colonnes CN sont [date, numérique (24)]. (Juste deux colonnes dans cet index particulier).
user606723
2

Je vais essayer de répondre uniquement à la première question. Si vous pouvez estimer approximativement depuis le début le nombre d'enregistrements que vous aurez dans vos tables après un certain temps, je dirais qu'il vaut mieux commencer par le début pour concevoir certains index. Essayez d'utiliser des outils de test ou des scripts de test qui automatiseront autant d'appels que possible pour les appels d'application qui, selon vous, seront le plus souvent utilisés et vous verrez quelles analyses de table peuvent être évitées dès le début.

Ce sera une supposition au début, mais avec le temps, comme vous avez des statistiques d'utilisation appropriées, vous aurez une image plus claire.

Marian
la source