La mia domanda riguarda Oracle 11g e l'uso di indici nelle query SQL.Oracle 11g: indice non utilizzato in "select distinct" -query
nel mio database, c'è un tavolo che è strutturato come segue:
Table tab (
rowid NUMBER(11),
unique_id_string VARCHAR2(2000),
year NUMBER(4),
dynamic_col_1 NUMBER(11),
dynamic_col_1_text NVARCHAR2(2000)
) TABLESPACE tabspace_data;
ho creato due indici:
CREATE INDEX Index_dyn_col1 ON tab (dynamic_col_1, dynamic_col_1_text) TABLESPACE tabspace_index;
CREATE INDEX Index_unique_id_year ON tab (unique_id_string, year) TABLESPACE tabspace_index;
La tabella contiene circa 1 a 2 milioni di dischi. Estraggo i dati da esso eseguendo il seguente comando SQL:
SELECT distinct
"sub_select"."dynamic_col_1" "AS_dynamic_col_1","sub_select"."dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM
(
SELECT "tab".* FROM "tab"
where "tab".year = 2011
) "sub_select"
Sfortunatamente, la query richiede circa 1 ora per eseguire, anche se ho creato gli indici entrambi sopra descritti. Il piano spiega che Oracle utilizza un "Accesso completo alla tabella", ovvero una scansione completa della tabella. Perché l'indice non viene utilizzato?
Come esperimento, ho testato il seguente comando SQL:
SELECT DISTINCT
"dynamic_col_1" "AS_dynamic_col_1", "dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM "tab"
Anche in questo caso, l'indice non viene utilizzato e viene eseguita una scansione completa della tabella.
Nel mio vero database, la tabella contiene più colonne indicizzate come "dynamic_col_1" e "dynamic_col_1_text". L'intero file indice ha una dimensione di circa 50 GB.
Un paio di informazioni:
- il database è Oracle 11g installato sul mio computer locale.
- Uso Windows 7 Enterprise 64 bit.
- L'intero indice è suddiviso su 3 file dbf con circa 50 GB di dimensione.
Sarei davvero felice se qualcuno potesse dirmi come rendere Oracle l'indice nella prima query. Poiché la prima query viene utilizzata da un altro programma per estrarre i dati dal database, difficilmente può essere modificata. Quindi sarebbe bene modificare il tavolo invece.
Grazie in anticipo.
[01.10.2011: UPDATE]
Credo di aver trovato la soluzione per il problema. Entrambe le colonne dynamic_col_1
e dynamic_col_1_text
sono annullabili. Dopo aver modificato la tabella per vietare i valori "NULL" in entrambe le colonne e aggiungere un nuovo indice esclusivamente per la colonna year
, Oracle esegue una scansione dell'indice rapido. Il vantaggio è che la query richiede ora circa 5 secondi per l'esecuzione e non 1 ora come prima.
Il campo 'rowid' è la chiave primaria? –
Si prega di non chiamare una colonna in un rowid tabella, stai chiedendo un mondo di dolore se hai mai avuto bisogno di utilizzare il vero [rowid pseudo-colonna] (http://download.oracle.com/docs/cd /B19306_01/server.102/b14200/pseudocolumns008.htm) – Ben
@BogdanSahlean Sì, rowid è la chiave primaria –