Różnica polega na tym, że zbieranie statystyk odświeża metadane dotyczące bieżącego indeksu, podczas gdy upuszczanie i ponowne tworzenie indeksu to, er, upuszczanie i ponowne tworzenie indeksu.
Być może łatwo jest zrozumieć różnicę na przećwiczonym przykładzie. Stwórzmy więc tabelę i 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>
Od 11g Oracle automatycznie gromadzi statystyki podczas tworzenia indeksu. Tak więc tworzenie indeksu i ostatnia analiza pokazują tę samą datę i godzinę. W poprzednich wersjach musieliśmy jawnie zbierać statystyki po utworzeniu indeksu. Dowiedz się więcej .
Następnie dodamy trochę danych i odświeżymy statystyki:
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>
Teraz zmieniły się metadane dotyczące statystyk, ale indeks jest tym samym obiektem bazy danych. Natomiast jeśli usuniemy i ponownie utworzymy indeks, otrzymamy nowy obiekt bazy danych:
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>
W normalnych operacjach prawie nigdy nie musimy upuszczać i ponownie tworzyć indeksu. Jest to technika, która jest czasami odpowiednia podczas ładowania bardzo dużych ilości danych oraz w bardzo rzadkich przypadkach uszkodzenia indeksu. W sieciach wciąż pojawiają się witryny, które zalecają regularne odbudowywanie indeksów ze względu na wydajność (podobno „zrównoważy” to przekrzywione indeksy), ale te witryny nie tworzą benchmarków, aby udowodnić długoterminowe korzyści, a na pewno nigdy nie uwzględniają czasu i Cykle procesora zmarnowane przez ćwiczenie odbudowy.
Przebudowa indeksu wymaga więcej pracy niż odświeżenie statystyk. Oczywiście to prawda, ponieważ przebudowa obejmuje zbieranie statystyk jako podzadanie. Pytanie brzmi, czy bardziej efektywne jest wykonywanie zbiorczego DML w odniesieniu do tabeli z jej indeksami w porównaniu z usuwaniem indeksów i ponownym tworzeniem ich później. Załadowanie danych do tabeli bez indeksów i późniejsze ich ponowne utworzenie może być szybsze.
Nie ma tutaj sztywnych i szybkich reguł:zależy to od liczby posiadanych indeksów, proporcji wierszy, na które ma to wpływ w stosunku do całego rozmiaru tabeli , czy potrzebne są indeksy do wymuszenia ograniczeń integralności relacyjnej i tak dalej. Istnieje również duża różnica między operacjami:możesz chcieć usunąć indeksy dla wstawiania zbiorczego, ale zachować je do aktualizacji, w zależności od tego, jakie indeksy są potrzebne dla klauzuli WHERE i czy aktualizacja wpływa na indeksowane kolumny.
Krótko mówiąc, musisz przetestować swój własny scenariusz. Często jest to odpowiedź na pytania dotyczące wydajności.