Mi pregunta se refiere a Oracle 11g y al uso de índices en consultas SQL.Oracle 11g: Índice no utilizado en "select distinct" -query
En mi base de datos, no es una tabla que está estructurado como sigue:
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;
He creado dos índices:
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 tabla contiene alrededor de 1 a 2 millones de registros. Puedo extraer los datos de la misma mediante la ejecución del siguiente 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"
Por desgracia, la consulta necesita alrededor de 1 hora para ejecutar, a pesar de que he creado los índices de ambas descritas anteriormente. El plan de explicación muestra que Oracle utiliza un "Acceso completo a la tabla", es decir, una exploración de tabla completa. ¿Por qué no se usa el índice?
Como un experimento, he probado el siguiente comando SQL:
SELECT DISTINCT
"dynamic_col_1" "AS_dynamic_col_1", "dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM "tab"
Incluso en este caso, el índice no se utiliza y se realiza un escaneo completo de tabla.
En mi base de datos real, la tabla contiene más columnas indexadas como "dynamic_col_1" y "dynamic_col_1_text". El archivo de índice completo tiene un tamaño de aproximadamente 50 GB.
Un poco más de información:
- La base de datos es Oracle 11g instalado en el ordenador local.
- Uso Windows 7 Enterprise 64bit.
- El índice completo está dividido en 3 archivos dbf con un tamaño de aproximadamente 50 GB.
Realmente me alegraría si alguien pudiera decirme cómo hacer que Oracle use el índice en la primera consulta. Como la primera consulta es utilizada por otro programa para extraer los datos de la base de datos, apenas se puede cambiar. Entonces, sería bueno modificar la mesa.
Gracias de antemano.
[01.10.2011: UPDATE]
creo que he encontrado la solución para el problema. Ambas columnas dynamic_col_1
y dynamic_col_1_text
son nulables. Después de alterar la tabla para prohibir los valores "NULOS" en ambas columnas y agregar un nuevo índice únicamente para la columna year
, Oracle realiza una Exploración rápida de índice. La ventaja es que la consulta tarda unos 5 segundos en ejecutarse y no 1 hora como antes.
'rowid' campo es la clave principal? –
Por favor, no llame a una columna en una tabla rowid, usted está pidiendo un mundo de dolor si alguna vez necesita usar el [row-pseudo-column] actual (http://download.oracle.com/docs/cd /B19306_01/server.102/b14200/pseudocolumns008.htm) – Ben
@BogdanSahlean Sí, rowid es la clave principal –