/ / Oracle: Indeksowanie podzbioru wierszy tabeli - sql, bazy danych, oracle, indeksowania

Oracle: indeksowanie podzbioru wierszy tabeli - sql, bazy danych, Oracle, indeksowania

Mam tabelę, która ma aktywne nieaktywne wpisy, aktywna = 1 dla aktywnych i aktywna = 0 dla nieaktywnych.

Mam różne indeksy na tej tabeli, ale japotrzebne są tylko indeksy utrzymywane dla aktywnych wpisów, ponieważ aplikacja odpytuje tylko o aktywne dane. Nieaktywne dane muszą być przechowywane, ponieważ mogą ponownie stać się aktywne, ale zazwyczaj odbywa się to tylko przy zbiorczych aktualizacjach, które i tak nie używają indeksu.

Zauważam, że indeksowanie nieaktywnych wpisów (jest ich więcej niż aktywnych) zajmuje sporo miejsca.

Czy w Oracle (10g) jest sposób na zrobienie czegoś takiego:

create index an_idx on tab (active, col1, col2, ... , coln) where active = 1?

Poprzednia próba:

Próbowałem użyć indeksu opartego na funkcji, aby ustawić pierwszą kolumnę na null, gdy active = 0 jak na przykład:

create index an_idx on tab (decode(active, 1, 1, null), col1, col2, ... , coln)

Jednak Oracle nadal wydaje się indeksować nieaktywne kolumny w tym przypadku.

Odpowiedzi:

7 dla odpowiedzi № 1

Podziel tabelę na ACTIVE, utwórz indeksy lokalne i uczyń indeksy nieaktywnych partycji NIEDOPUSZCZALNE. Pozwoli to wyeliminować czas poświęcony na indeksowanie nieaktywnych danych.

create table tab(active number, col1 number, col2 number, col3 number)
partition by list(active)
(partition tab_active values(1), partition tab_inactive values(0));

create index tab_index1 on tab(col1) local;

alter index tab_index1 modify partition tab_inactive unusable;

Istnieje jednak kilka potencjalnych wad tego podejścia:

  • Nie wszystkie typy indeksów mogą być bezużyteczne.
  • Nie jest normalne, że w bazie danych znajdują się obiekty, które nie nadają się do użytku. Ludzie prawdopodobnie narzekają na to lub zakładają, że jest to błąd i odbudowuje go.
  • Niektóre operacje, takie jak obcinanie, automatycznie ponownie nadają indeksom użyteczność.

W Oracle 12c możesz tego dokonać indeksy częściowe:

create table tab(active number, col1 number, col2 number, col3 number)
partition by list(active)
(partition tab_active   values(1) indexing on,
partition tab_inactive values(0) indexing off);

create index tab_index1 on tab(col1) local indexing partial;

11 dla odpowiedzi nr 2

Twoja podstawowa idea jest właściwa, ale musisz zastosować dekodowanie do wszystkich kolumn. Tylko wtedy, gdy wszystkie indeksowane wyrażenia są NULL czy wiersz nie zostanie zindeksowany.

create index an_idx on tab (
decode(active, 1, col1, null),
...
decode(active, 1, coln, null)
)

Oczywiście, jeśli chcesz, aby zapytanie używało tego indeksu, musi użyć tych samych wyrażeń w klauzuli WHERE.

Uwaga: Myślę, że nie chcesz dołączać wyrażenia decode(active, 1, 1, null) w indeksie, ponieważ byłby stały dla wszystkich indeksowanych wierszy.


1 dla odpowiedzi nr 3

Nie sądzę, żeby to było możliwe. Istnieje kilka opcji

  1. Utwórz indeks (aktywny, col1 ...), aby nie wpływać na czas zapytania tyle samo przez nieaktywne elementy
  2. Utwórz dwie tabele dla aktywnych / nieaktywnych elementów i zarządzaj aktywnym stanem, przenosząc rzeczy między dwiema tabelami
  3. Utwórz drugą tabelę ze wszystkimi danymi, które chcesz zindeksować, a także unikatowy identyfikator i dołącz do tabeli, aby uzyskać pozostałe dane.