sql >> Database >  >> RDS >> Oracle

Statistieken verzamelen op een index of creëren laten vallen?

Het verschil is dat het verzamelen van statistieken de metagegevens over de huidige index ververst, terwijl het verwijderen en opnieuw maken van de index, eh, het verwijderen en opnieuw maken van de index is.

Misschien is het verschil gemakkelijk te begrijpen met een uitgewerkt voorbeeld. Laten we dus een tabel en een index maken:

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> 

Sinds 11g verzamelt Oracle automatisch statistieken wanneer we een index maken. Dus indexcreatie en laatste analyse tonen dezelfde datetime. In eerdere versies moesten we expliciet statistieken verzamelen nadat we de index hadden gemaakt. Meer informatie .

Vervolgens voegen we wat gegevens toe en vernieuwen we de statistieken:

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 zijn de metadata met betrekking tot statistieken veranderd, maar de index is hetzelfde database-object. Terwijl als we de index verwijderen en opnieuw maken, we een nieuw database-object krijgen:

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> 

Bij normale operaties hoeven we bijna nooit een index te laten vallen en opnieuw te maken. Het is een techniek die soms geschikt is bij het laden van zeer grote hoeveelheden gegevens en in zeer zeldzame gevallen van indexcorruptie. De interwebs geven nog steeds sites op die om prestatieredenen aanbevelen om regelmatig indexen opnieuw op te bouwen (naar verluidt "herbalanceert" het scheve indexen), maar deze sites produceren niet de benchmarks om de voordelen op lange termijn te bewijzen, en nemen zeker nooit de tijd en CPU-cycli verspild door de herbouwoefening.

Het opnieuw opbouwen van een index vereist meer werk dan het vernieuwen van de statistieken. Het is duidelijk waar, want het opnieuw opbouwen omvat het verzamelen van statistieken als een subtaak. De vraag is of het efficiënter is om bulk-DML uit te voeren tegen een tabel met zijn indexen op zijn plaats in vergelijking met het laten vallen van de indexen en het opnieuw maken van de indexen daarna. Het kan sneller zijn om gegevens zonder indexen in een tabel te laden en ze daarna opnieuw te maken.

Er is hier geen vaste regel:het hangt af van hoeveel indexen je hebt, het aandeel van de betrokken rijen ten opzichte van de hele grootte van de tabel, of je de indexen nodig hebt om relationele integriteitsbeperkingen af ​​te dwingen, enzovoort. Er is ook een groot verschil tussen bewerkingen:u wilt misschien indexen voor bulkinvoegingen verwijderen, maar ze behouden voor updates, afhankelijk van welke indexen u nodig heeft voor uw WHERE-component en of de update van invloed is op geïndexeerde kolommen.

Kortom, u moet uw eigen specifieke scenario benchmarken. Dit is vaak het antwoord als het gaat om prestatievragen.




  1. Geen module met de naam MySQLdb, zelfs als MySQL-python is geïnstalleerd?

  2. Tijdzonewaarde van gegevens wijzigen

  3. Hoe IIF() werkt in SQL Server

  4. Basisprincipes van SQL Server-transactielogboek