Oracle
 sql >> Base de données >  >> RDS >> Oracle

Recueillir des statistiques sur un index ou supprimer des créations ?

La différence est que la collecte de statistiques actualise les métadonnées sur l'index actuel, tandis que la suppression et la recréation de l'index consistent, euh, à supprimer et à recréer l'index.

Il est peut-être facile de comprendre la différence avec un exemple concret. Créons donc une table et un index :

SQL> create table t23 
  2  as select object_id as id, object_name as name from user_objects 
  3  /

Table created.

SQL> create index i23 on t23(id)
  2  /

Index created.

SQL> select o.object_id, i.last_analyzed, i.distinct_keys
  2  from user_objects o
  3       join user_indexes i
  4            on (i.index_name = o.object_name)
  5  where o.object_type = 'INDEX'
  6  and i.index_name = 'I23'
  7  /

 OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
---------- -------------------- -------------------- -------------
    116353 23-NOV-2013 00:15:39 23-NOV-2013 00:15:39           167

1 row selected.

SQL> 

Depuis 11g, Oracle rassemble automatiquement des statistiques lorsque nous créons un index. Ainsi, la création d'index et la dernière analyse affichent la même date/heure. Dans les versions précédentes, nous devions collecter explicitement des statistiques après avoir créé l'index. En savoir plus .

Ensuite, nous allons ajouter des données et actualiser les statistiques :

SQL> insert into t23 values (9999, 'TEST1')
  2  /

1 row created.

SQL> insert into t23 values (-8888, 'TEST 2')
  2  /

1 row created.

SQL> exec dbms_stats.gather_index_stats(user, 'I23') 

PL/SQL procedure successfully completed.

SQL> select o.object_id, i.last_analyzed, i.distinct_keys
  2  from user_objects o
  3       join user_indexes i
  4            on (i.index_name = o.object_name)
  5  where o.object_type = 'INDEX'
  6  and i.index_name = 'I23'
  7  /

 OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
---------- -------------------- -------------------- -------------
    116353 23-NOV-2013 00:15:39 23-NOV-2013 00:26:28           169

1 row selected.

SQL> 

Désormais, les métadonnées relatives aux statistiques ont changé, mais l'index est le même objet de base de données. Alors que si nous supprimons et recréons l'index, nous obtenons un nouvel objet de base de données :

SQL> drop index i23
  2  /

Index dropped.

SQL> create index i23 on t23(id) 
  2  /

Index created.

SQL> select o.object_id, i.last_analyzed, i.distinct_keys
  2  from user_objects o
  3       join user_indexes i
  4            on (i.index_name = o.object_name)
  5  where o.object_type = 'INDEX'
  6  and i.index_name = 'I23'
  7  /

 OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
---------- -------------------- -------------------- -------------
    116354 23-NOV-2013 00:27:50 23-NOV-2013 00:27:50           169

1 row selected.

SQL> 

Dans des opérations normales, nous n'avons presque jamais besoin de supprimer et de recréer un index. C'est une technique qui est parfois appropriée lors du chargement de très grandes quantités de données et dans de très rares cas de corruption d'index. Les interwebs lancent toujours des sites qui recommandent une reconstruction régulière des index pour des raisons de performances (prétendument, cela "rééquilibre" les index biaisés), mais ces sites ne produisent pas les références pour prouver les avantages à long terme, et n'incluent certainement jamais le temps et Cycles CPU gaspillés par l'exercice de reconstruction.

La reconstruction d'un index nécessite plus de travail que l'actualisation des statistiques. Évidemment vrai, car la reconstruction inclut la collecte de statistiques en tant que sous-tâche. La question est de savoir s'il est plus efficace d'entreprendre un DML en bloc sur une table avec ses index en place par rapport à la suppression des index et à la recréation par la suite. Il peut être plus rapide de charger des données dans une table sans index et de les recréer ensuite.

Il n'y a pas de règle absolue ici :cela dépend du nombre d'index que vous avez, de la proportion de lignes affectées par rapport à la taille totale de la table , si vous avez besoin des index pour appliquer des contraintes d'intégrité relationnelle, etc. Il existe également une grande différence entre les opérations :vous pouvez supprimer les index pour les insertions en masse, mais les conserver pour les mises à jour, en fonction des index dont vous avez besoin pour votre clause WHERE et si la mise à jour affecte les colonnes indexées.

En bref, vous devez évaluer votre propre scénario spécifique. C'est souvent la réponse lorsqu'il s'agit de questions sur les performances.