La mia intenzione è ottenere un set di risultati impaginato dei clienti. Sto usando questo algoritmo, da Tom:Perché Oracle ignora l'indice con 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;
Ho anche un indice definito sulla colonna "CLIENTE" "FIRST_NAME":.
CREATE INDEX CUSTOMER_FIRST_NAME_TEST ON CUSTOMER (FIRST_NAME ASC);
La query restituisce il gruppo di risultati attesi, ma dal spiegare il piano noto che l'indice non è utilizzato:
--------------------------------------------------------------------------------------
| 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)
Sto usando Oracle 11g. Poiché ho appena richiesto le prime 20 righe, ordinate dalla colonna indicizzata, mi aspetto che venga utilizzato l'indice.
Perché l'ottimizzatore Oracle ignora l'indice? Immagino sia qualcosa di sbagliato nell'algoritmo di impaginazione, ma non riesco a capire cosa.
Grazie.
+1 Sarebbe bello sapere perché Oracle non può utilizzare un indice per una colonna 'nullable'. – Andomar
può. ma solo se almeno UNA colonna nell'indice NON è NULLABLE. vedi, in oracolo, le chiavi NULL non sono nell'indice. – DazzaL
ad esempio: 'SQL> crea l'indice c sul cliente (first_name, id);' se l'ID è una colonna non annullabile si ottiene anche il risultato desiderato. se non hai colonne che non sono annullabili (wierd), allora crea un indice di funzione come 'crea l'indice c sul cliente (first_name, 0);' lo zero letterale non è sempre nullo, quindi forza ogni riga nulla nell'indice. – DazzaL