2010-11-19 16 views
10

Tengo una vista y quiero consultar mi vista de esa manera para insinuar algún índice de una tabla base, ¿puedo hacerlo?¿Usa sugerencias para las vistas?

quiero decir:

--view 
create or replace view temp_view 
as select col1,col2,col3 
from table1,table2.... 

que tienen un índice en table1.col1 llamado "index1".

Tengo una consulta :

--query 
select * 
from temp_view 
where col1=12; 

Y cuando veo a explicar el plan de esta consulta que me muestra que la consulta no utiliza "index1" y quiero indicar que ..

Así que queremos que sea, por ejemplo:

--query with hint 
select /*+ index(temp_view index1)*/* 
from temp_view 
where col1=12; 

¿Puedo indicar pistas para vistas ?? (Si no quiero indicarlo durante la creación de esta vista)

+0

He probado y no funciona Me refiero a este/* + índice (temp_view index1) */no funciona ... He escrito esto aquí porque quiero saber de otra manera si existe para indicar sugerencia para las vistas. No quiero cambiar la vista porque esta vista es creada por otro usuario y no es correcto cambiar su vista. – kupa

+0

y una cosa más que quiero preguntar ... ¿Conoces algunos tutoriales útiles que me darán un buen conocimiento sobre cómo optimizar las consultas mediante sugerencias? por favor – kupa

+0

@ACP ¿qué editaste? : D: D No encontré ninguna edición en mi publicación: D – kupa

Respuesta

12

Puede usar una sugerencia en una consulta en una vista para obligar a Oracle a usar un índice en la tabla base. Pero necesita saber el alias de la tabla base (si corresponde) en la vista subyacente. La sintaxis general sería /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

Un ejemplo

1) crear una tabla con 10.000 filas idénticas y crear un índice en la tabla. El índice no será selectivo, por lo que Oracle no querrá usarlo

SQL> ed 
Wrote file afiedt.buf 

    1 create table foo 
    2 as 
    3 select 1 col1 
    4 from dual 
    5* connect by level <= 10000 
SQL>/

Table created. 

SQL> create index idx_foo on foo(col1); 

Index created. 

2) Verificar que el índice no se utiliza normalmente, pero que Oracle va a usar con un toque

SQL> set autotrace traceonly; 
SQL> select * from foo where col1 = 1; 

10000 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1245013993 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  | 10000 | 126K|  7 (0)| 00:00:01 | 
|* 1 | TABLE ACCESS FULL| FOO | 10000 | 126K|  7 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

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

    1 - filter("COL1"=1) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
      9 recursive calls 
      0 db block gets 
     713 consistent gets 
      5 physical reads 
      0 redo size 
    172444 bytes sent via SQL*Net to client 
     7849 bytes received via SQL*Net from client 
     668 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     10000 rows processed 

SQL> select /*+ index(foo idx_foo) */ * 
    2 from foo 
    3 where col1 = 1; 

10000 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 15880034 

---------------------------------------------------------------------------- 
| Id | Operation  | Name | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |   | 10000 | 126K| 25 (0)| 00:00:01 | 
|* 1 | INDEX RANGE SCAN| IDX_FOO | 10000 | 126K| 25 (0)| 00:00:01 | 
---------------------------------------------------------------------------- 

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

    1 - access("COL1"=1) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
      7 recursive calls 
      0 db block gets 
     715 consistent gets 
     15 physical reads 
      0 redo size 
    172444 bytes sent via SQL*Net to client 
     7849 bytes received via SQL*Net from client 
     668 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     10000 rows processed 

3) Ahora crea la vista. Verificar que las consultas normales contra la opinión de no utilizar el índice, pero forzar el índice que se utiliza especificando tanto la opinión de alias en la consulta y el alias de la tabla de la definición de la vista

SQL> create view vw_foo 
    2 as 
    3 select col1 
    4 from foo f; 

View created. 

SQL> select col1 
    2 from vw_foo 
    3 where col1 = 1; 

10000 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1245013993 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  | 10000 | 126K|  7 (0)| 00:00:01 | 
|* 1 | TABLE ACCESS FULL| FOO | 10000 | 126K|  7 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

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

    1 - filter("COL1"=1) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
     16 recursive calls 
      0 db block gets 
     715 consistent gets 
      0 physical reads 
      0 redo size 
    172444 bytes sent via SQL*Net to client 
     7849 bytes received via SQL*Net from client 
     668 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     10000 rows processed 

SQL> select /*+ index(vf f idx_foo) */ col1 
    2 from vw_foo vf 
    3 where col1 = 1; 

10000 rows selected. 


Execution Plan 
---------------------------------------------------------- 
Plan hash value: 15880034 

---------------------------------------------------------------------------- 
| Id | Operation  | Name | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |   | 10000 | 126K| 25 (0)| 00:00:01 | 
|* 1 | INDEX RANGE SCAN| IDX_FOO | 10000 | 126K| 25 (0)| 00:00:01 | 
---------------------------------------------------------------------------- 

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

    1 - access("COL1"=1) 

Note 
----- 
    - dynamic sampling used for this statement (level=2) 


Statistics 
---------------------------------------------------------- 
     14 recursive calls 
      0 db block gets 
     717 consistent gets 
      0 physical reads 
      0 redo size 
    172444 bytes sent via SQL*Net to client 
     7849 bytes received via SQL*Net from client 
     668 SQL*Net roundtrips to/from client 
      0 sorts (memory) 
      0 sorts (disk) 
     10000 rows processed 

SQL> 

Dicho todo esto, sin embargo, en general, los consejos son un último recurso cuando se trata de sintonizar una consulta; por lo general, es preferible averiguar qué información falta en el optimizador y proporcionar estadísticas adecuadas para que pueda tomar la decisión correcta por sí mismo. Esa es una solución mucho más estable en el futuro. Por lo tanto, cuando se reduce a especificar sugerencias que involucran varias capas de alias, es demasiado fácil para alguien que toca la definición de la vista romper su consulta cambiando el alias del nombre de la tabla, por ejemplo.

+0

+1 Forma más completa que la respuesta que acabo de abandonar :) También estoy de acuerdo con los consejos sobre sugerencias de ajuste como último recurso. – APC

+0

Muchas gracias Tengo la mejor respuesta ... Gracias por su ayuda ... Estoy realmente sorprendido ...¿Y puedo preguntarle algo acerca de cómo profundizar mi conocimiento acerca de las sugerencias SQL? Estoy buscando un buen tutorial – kupa

+0

Y cuál es una forma preferible de identificar qué sqls son "malas" y comprobar si lo ha ajustado bien ... Como veo, utilizas "set autotrace traceonly;" ¿no usas v $ sql_longops o ADDM? – kupa

Cuestiones relacionadas