2012-08-15 23 views
5

En una tabla de nuestra instalación de Oracle, tenemos una tabla con un índice en dos de las columnas (X e Y). Si realizo una consulta en la tabla con una cláusula where solo tocando la columna X, ¿Oracle podrá usar el índice?Índice de Oracle con múltiples columnas que consultan en una sola columna

Por ejemplo:

Tabla Y: col_a, col_b, col_c, existe

índice en (col_a, col_b)

SELECT * FROM Table_Y WHERE Col_A = 'STACKOVERFLOW'; 

se utilizará el índice, o va un escaneo de tabla debe hacerse?

Respuesta

9

Depende.

Se puede comprobar que al permitir que Oracle explicar el plan de ejecución:

EXPLAIN PLAN FOR 
    SELECT * FROM Table_Y WHERE Col_A = 'STACKOVERFLOW'; 

y luego

select * from table(dbms_xplan.display); 

Así, por ejemplo, con

create table table_y (
    col_a varchar2(30), 
    col_b varchar2(30), 
    col_c varchar2(30) 
); 

create unique index table_y_ix on table_y (col_a, col_b); 

y luego un

explain plan for 
    select * from table_y 
    where col_a = 'STACKOVERFLOW'; 

select * from table(dbms_xplan.display); 

El plan (en mi instalación) se parece a:

------------------------------------------------------------------------------------------ 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT   |   |  1 | 51 |  1 (0)| 00:00:01 | 
| 1 | TABLE ACCESS BY INDEX ROWID| TABLE_Y |  1 | 51 |  1 (0)| 00:00:01 | 
|* 2 | INDEX RANGE SCAN   | TABLE_Y_IX |  1 |  |  1 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------ 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    2 - access("COL_A"='STACKOVERFLOW') 

ID 2 muestra, que el índice TABLE_Y_IX sean efectivamente utilizados en un index range scan.

Si en otra instalación Oracle elige usar el índice depende de muchas cosas. Es el optimizador de consultas de Oracle que toma esta decisión.

actualización Si usted siente que está mejor fuera (se refiere a rendimiento, es decir) si Oracle utiliza el índice, es posible que desee probar el + index_asc(...) (ver index hint)

Así, en su caso que lo haría ser algo así como

SELECT /*+ index_asc(TABLE_Y TABLE_Y_IX) */ * 
    FROM Table_Y 
WHERE Col_A = 'STACKOVERFLOW'; 

Además, me aseguraré de que haya recopilado estadísticas sobre la tabla y sus columnas. Puede comprobar la fecha de la última reunión de la estadística con un

select last_analyzed from dba_tables where table_name = 'TABLE_Y'; 

y

select column_name, last_analyzed from dba_tab_columns where table_name = 'TABLE_Y'; 

Si no hay estadísticas o si son rancio, que se familiarice con el paquete dbms_stats para obtener dicha estadística.

Estas estadísticas son los datos que el optimizador de consultas se basa en gran medida para tomar sus decisiones.

+0

Perfecto, eso ayuda mucho.Como un aparte, mi instalación informa un escaneo de tabla, pero al menos ahora tengo la capacidad de verificar. –

+0

Solo me pregunto. La selección del plan de ejecución no depende de si está eligiendo la primera o la segunda columna en el índice. Es decir, si está eligiendo la primera columna, obtendrá un escaneo de rango de índice, pero si está seleccionando la segunda columna, ¿obtendrá un escaneo de tabla completo? – Gisli

+1

@Gisli: Oracle puede optar por usar el índice para una [exploración de salto de índice] (http://docs.oracle.com/cd/E11882_01/server.112/e16638/optimops.htm#PFGRF10105) en su escenario. –

Cuestiones relacionadas