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

Indsamle statistik på et indeks eller droppe oprettelse?

Forskellen er, at indsamling af statistik opdaterer metadataene om det aktuelle indeks, mens at droppe og genskabe indekset er, eh, at droppe og genskabe indekset.

Måske er det let at forstå forskellen med et udført eksempel. Så lad os oprette en tabel og et indeks:

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> 

Da 11g Oracle automatisk samler statistik, når vi opretter et indeks. Så indeksoprettelse og sidste analyse viser den samme dato og klokkeslæt. I tidligere versioner var vi nødt til eksplicit at indsamle statistik, efter at vi oprettede indekset. Få mere at vide .

Dernæst tilføjer vi nogle data og opdaterer statistikken:

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> 

Nu er metadataene vedrørende statistik ændret, men indekset er det samme databaseobjekt. Hvorimod hvis vi dropper og genskaber indekset, får vi et nyt databaseobjekt:

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> 

I normal drift behøver vi næsten aldrig at droppe og genskabe et indeks. Det er en teknik, som til tider er passende ved indlæsning af meget store mængder data og i meget sjældne tilfælde af indekskorruption. Interwebs kaster stadig websteder op, som anbefaler regelmæssig genopbygning af indekser af præstationsmæssige årsager (angiveligt "genbalancerer" skæve indekser), men disse websteder producerer ikke benchmarks for at bevise de langsigtede fordele, og inkluderer bestemt aldrig tid og CPU-cyklusser spildt af genopbygningsøvelsen.

Genopbygning af et indeks kræver mere arbejde end at opdatere statistikken. Det er klart sandt, fordi genopbygning inkluderer indsamling af statistik som en underopgave. Spørgsmålet er, om det er mere effektivt at foretage bulk DML mod en tabel med dens indekser på plads sammenlignet med at droppe indeksene og genskabe efterfølgende. Det kan være hurtigere at indlæse data i en tabel uden indekser og genskabe dem bagefter.

Der er ingen fast-og-hurtig regel her:det afhænger af, hvor mange indekser du har, andelen af ​​rækkerne, der er påvirket af hele tabellens størrelse, om du har brug for indeksene til at håndhæve relationelle integritetsbegrænsninger, og så videre. Der er også en stor forskel mellem operationer:du ønsker måske at droppe indekser for masseindsættelser, men beholde dem til opdateringer, afhængigt af hvilke indekser du har brug for til din WHERE-klausul, og om opdateringen påvirker indekserede kolonner.

Kort sagt, du skal benchmarke dit eget specifikke scenarie. Dette er ofte svaret, når det kommer til præstationsspørgsmål.




  1. 3-cifret valutakode til valutasymbol

  2. Hvordan udskriver man nøjagtig sql-forespørgsel i zend framework?

  3. Parsing af JSON-data fra CLOB-feltet ved hjælp af PL/SQL

  4. MySQL COUNT med LIMIT