Quand faut-il supprimer et recréer les index?


9

Nous construisons un entrepôt de données qui sera initialement de 1 To et augmentera d'environ 20 Go par mois.

Pour certaines tables, nous effectuons des processus ETL quotidiens et d'autres, nous le faisons chaque semaine / chaque mois.

Quand une importation de données entre dans une table, est-il nécessaire de supprimer et recréer les index?

Est-il jamais utile de supprimer et de recréer des index ou sont-ils automatiquement mis à jour?

Les statistiques sont définies pour se mettre à jour automatiquement.

Merci beaucoup pour votre aide et vos conseils.

J'ai ce script génial:

SELECT 'ALTER INDEX [' + ix.name + '] ON [' + s.name + '].[' + t.name + '] ' +
       CASE WHEN ps.avg_fragmentation_in_percent > 40 THEN 'REBUILD' ELSE 'REORGANIZE' END +
       CASE WHEN pc.partition_count > 1 THEN ' PARTITION = ' + cast(ps.partition_number as nvarchar(max)) ELSE '' END
FROM   sys.indexes AS ix INNER JOIN sys.tables t
           ON t.object_id = ix.object_id
       INNER JOIN sys.schemas s
           ON t.schema_id = s.schema_id
       INNER JOIN (SELECT object_id, index_id, avg_fragmentation_in_percent, partition_number
                   FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL)) ps
           ON t.object_id = ps.object_id AND ix.index_id = ps.index_id
       INNER JOIN (SELECT object_id, index_id, COUNT(DISTINCT partition_number) AS partition_count
                   FROM sys.partitions
                   GROUP BY object_id, index_id) pc
           ON t.object_id = pc.object_id AND ix.index_id = pc.index_id
WHERE  ps.avg_fragmentation_in_percent > 10 AND
       ix.name IS NOT NULL

d'ici:

http://weblogs.asp.net/okloeten/archive/2009/01/05/6819737.aspx

Suggérez-vous que j'exécute ce script quotidiennement et que, sur la base des résultats, j'exécute le code généré?


je serais très reconnaissant si quelqu'un m'expliquait quel était le problème avec ma question
l --''''''---------------- '' '' '' '' '' ''

Voici une question connexe que j'ai posée. dba.stackexchange.com/questions/11389/… Les connaissances que j'ai acquises de cette question et les réponses m'ont beaucoup appris et nous avons réalisé de grands gains grâce à cela.
swasheck

Réponses:


13

S'il s'agit d'un ETL cyclique et que vous êtes dans un environnement de données de développement (c.-à-d. PAS EN DIRECT), vous devez certainement gérer vos index dans le cadre de votre cycle de chargement.

Je le fais pour plusieurs ensembles de données chaque mois, dont le plus important ajoute environ 100 Go par mois à un ensemble de données de 5 To.

J'ai fait des tests approfondis, et d'après ma propre expérience, le moyen le plus efficace de charger en ce qui concerne les index est:

  1. DISABLE index non clusterisés, laissant l'index clusterisé intact
  2. Effectuer le chargement de raw dans votre table de données
  3. REBUILD Index NC

Si vous ajoutez uniquement des lignes périodiquement dans le cadre d'ETL géré, c'est la voie à suivre. Cela garantit également que toutes vos statistiques sont à jour.

Pour les statistiques, il est important de noter que l'ajout de 20 Go à une base de données de 1 To n'atteindra pas le point de basculement pour une mise à jour automatique des statistiques, vous pouvez donc ajouter un mois entier de données sans jamais mettre à jour les statistiques.

La reconstruction de vos index CN est une bonne solution. Vous pouvez également effectuer une reconstruction d'index en cluster périodiquement si la fragmentation devient élevée (en fonction de la structure de votre table et de votre clé en cluster).


4
Vous pouvez également mettre à jour les statistiques en tant que partie distincte de votre processus, mélangé entre les reconstructions NC si cela est souvent trop cher.
Aaron Bertrand

1

Pour une base de données 1 To +, supprimer et créer des index quotidiennement serait exagéré (même si vous ne recréez que certains d'entre eux).

Si vous vous inquiétez des vitesses d'insertion / mise à jour dans votre table en raison de la surcharge ajoutée par les mises à jour d'index, je recommande deux choses:

  1. Utilisez des PK de substitution afin que les insertions d'index en cluster aient une surcharge minimale.
  2. Profilez votre DWH et créez des index non clusterisés lorsque cela est absolument nécessaire.

Vous devrez vivre avec des mises à jour d'index non clusterisées lors des opérations d'insertion / mise à jour.

Si vous êtes préoccupé par la fragmentation des index, je vous recommande de créer des travaux quotidiens (travaux de l'Agent SQL) pour reconstruire les index. La période de reconstruction peut en fait être n'importe quoi, dépend du niveau de fragmentation. Vous devriez le remarquer dans la pratique et configurer le calendrier de travail en conséquence.

Vous pouvez ajouter une logique aux scripts de reconstruction, selon le niveau de fragmentation. Quelques bonnes lignes directrices que vous pouvez trouver ici .

En fin de compte, vous ne devez en aucun cas effectuer une reconstruction d'index complète sur une base de données de cette taille.


6
Je dois être en désaccord avec beaucoup de cela. Cela dépendra de son cas d'utilisation, mais cette dernière ligne under any circumstances you shouldn't do a full index rebuild on a database of that size.n'est pas exacte du tout. Je fais ETL sur de très grandes bases de données comme tâche principale et je vois d'énormes avantages de désactiver et de reconstruire les index.
JNK

1
Je souhaite que cela s'applique également à mon cas. Sur une base de données légèrement supérieure à 1 To fonctionnant dans un environnement de production, je peux à peine me permettre de reconstruire un index non clusterisé de nuit pour plusieurs tables de plus de 500 mil. Lignes. J'ai plusieurs processus ETL en cours d'exécution chaque nuit et la dernière étape que je fais à partir de 3h00 est de reconstruire les index.
Marcel N.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.