Oracle
 sql >> Database >  >> RDS >> Oracle

Raccogli le statistiche su un indice o elimina la creazione?

La differenza è che la raccolta di statistiche aggiorna i metadati sull'indice corrente mentre eliminare e ricreare l'indice significa, ehm, eliminare e ricreare l'indice.

Forse è facile capire la differenza con un esempio lavorato. Quindi creiamo una tabella e un indice:

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> 

Poiché 11g Oracle raccoglie automaticamente le statistiche quando creiamo un indice. Quindi la creazione dell'indice e l'ultima analisi mostrano la stessa data e ora. Nelle versioni precedenti dovevamo raccogliere statistiche in modo esplicito dopo aver creato l'indice. Scopri di più .

Successivamente, aggiungeremo alcuni dati e aggiorneremo le statistiche:

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> 

Ora i metadati relativi alle statistiche sono cambiati ma l'indice è lo stesso oggetto database. Considerando che se eliminiamo e ricreiamo l'indice otteniamo un nuovo oggetto database:

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> 

Nelle normali operazioni non abbiamo quasi mai bisogno di eliminare e ricreare un indice. È una tecnica che a volte è appropriata quando si caricano quantità molto grandi di dati e in casi molto rari di danneggiamento dell'indice. Gli interweb continuano a generare siti che raccomandano la ricostruzione regolare degli indici per motivi di prestazioni (presumibilmente "ribilancia" gli indici distorti) ma questi siti non producono i benchmark per dimostrare i vantaggi a lungo termine e certamente non includono mai il tempo e Cicli della CPU sprecati dall'esercizio di ricostruzione.

La ricostruzione di un indice richiede più lavoro rispetto all'aggiornamento delle statistiche. Ovviamente vero, perché la ricostruzione include la raccolta di statistiche come attività secondaria. La domanda è se sia più efficiente eseguire DML in blocco su una tabella con i relativi indici rispetto all'eliminazione degli indici e alla ricreazione di quelli successivi. Può essere più rapido caricare i dati in una tabella senza indici e ricrearli in seguito.

Non esiste una regola rigida qui:dipende da quanti indici hai, dalla proporzione delle righe interessate rispetto all'intera dimensione della tabella, se hai bisogno degli indici per applicare i vincoli di integrità relazionale e così via. C'è anche una grande differenza tra le operazioni:potresti voler eliminare gli indici per gli inserimenti in blocco ma conservarli per gli aggiornamenti, a seconda degli indici necessari per la tua clausola WHERE e se l'aggiornamento influisce sulle colonne indicizzate.

In breve, è necessario confrontare il proprio scenario specifico. Questa è spesso la risposta quando si tratta di domande sul rendimento.