Moim zamiarem jest uzyskanie paginowanego zestawu wyników klientów. Używam tego algorytmu, z Tom:Dlaczego Oracle ignoruje indeks z ORDER BY?
select * from (
select /*+ FIRST_ROWS(20) */ FIRST_NAME, ROW_NUMBER() over (order by FIRST_NAME) RN
from CUSTOMER C
)
where RN between 1 and 20
order by RN;
Mam też indeks zdefiniowany w kolumnie „Klient” „imię”.
CREATE INDEX CUSTOMER_FIRST_NAME_TEST ON CUSTOMER (FIRST_NAME ASC);
Kwerenda zwraca oczekiwaną resultset, ale z wyjaśnij plan Zwróć uwagę, że indeks nie jest używany:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 15467 | 679K| 157 (3)| 00:00:02 |
| 1 | SORT ORDER BY | | 15467 | 679K| 157 (3)| 00:00:02 |
|* 2 | VIEW | | 15467 | 679K| 155 (2)| 00:00:02 |
|* 3 | WINDOW SORT PUSHED RANK| | 15467 | 151K| 155 (2)| 00:00:02 |
| 4 | TABLE ACCESS FULL | CUSTOMER | 15467 | 151K| 154 (1)| 00:00:02 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("RN">=1 AND "RN"<=20)
3 - filter(ROW_NUMBER() OVER (ORDER BY "FIRST_NAME")<=20)
Używam Oracle 11g. Ponieważ właśnie szukam pierwszych 20 wierszy, uporządkowanych według indeksowanej kolumny, spodziewałbym się użycia indeksu.
Dlaczego optymalizator Oracle ignoruje indeks? Zakładam, że jest to coś nie tak z algorytmem stronicowania, ale nie wiem, co.
Dzięki.
+1 Byłoby miło wiedzieć, dlaczego firma Oracle nie może używać indeksu dla kolumny 'nullable'. – Andomar
może. ale tylko jeśli co najmniej JEDNA kolumna w indeksie NIE JEST NULLABLe. widzisz, w oracle, klucze NULL nie znajdują się w indeksie. – DazzaL
np .: 'SQL> utwórz indeks c na kliencie (first_name, id);' jeśli ID jest kolumną nie podlegającą zerowaniu, uzyskasz także pożądany wynik. jeśli nie masz żadnych kolumn, które nie są zerowalne (wierd), utwórz indeks funkcji, taki jak 'create index c na kliencie (first_name, 0);' literalna 0 zawsze ma wartość zerową, więc zmusza każdy wiersz zerowy do indeksu. – DazzaL