2010-11-19 11 views
10

Ho una vista e voglio interrogare la mia vista in quel modo per suggerire qualche indice da una tabella di base, posso farlo?Utilizzare i suggerimenti per le viste?

Voglio dire:

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

Ho un indice su table1.col1 chiamato "index1".

Ho un interrogazione:

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

E quando vedo spiegare piano di questa query mi mostra che query non usare "index1" e voglio indicare che ..

quindi voglio che sia, ad esempio:

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

Posso indicare suggerimenti per le viste ?? (Se io non voglio indicare che durante la creazione di questo punto di vista)

+0

ho provato e non funziona voglio dire questo/* + indice (temp_view index1) */Non work..I hanno scritto questo qui perché voglio sapere altro modo se esistono per indicare suggerimento per le visualizzazioni .. Non voglio cambiare vista perché questa vista è creata da un altro utente e non è giusto cambiare la sua vista. – kupa

+0

e un'altra cosa che voglio chiedere ... Conoscete alcuni tutorial utili che mi daranno una buona conoscenza di come ottimizzare le query con i suggerimenti? per favore – kupa

+0

@ ACP cosa hai modificato ?? : D: D Non ho trovato alcuna edizione nel mio post: D – kupa

risposta

12

È possibile utilizzare un suggerimento su una query al fine di forzare Oracle per utilizzare un indice sulla tabella di base. Ma è necessario conoscere l'alias della tabella di base (se presente) nella vista sottostante. La sintassi generale sarebbe /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

Un esempio

1) creare una tabella con 10.000 righe identici e crea un indice nella tabella. L'indice non sarà selettivo, quindi Oracle non vorrà 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) Verificare che l'indice non viene utilizzato normalmente ma che Oracle userà con un suggerimento

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) Ora crea la vista. Verificare che normali query la vista non utilizzare l'indice ma forzare l'indice da utilizzare specificando sia la vista alias nella query e l'alias tabella dalla definizione di 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> 

Detto questo, tuttavia, i suggerimenti in generale sono l'ultima risorsa quando si cerca di mettere a punto una query, in genere è preferibile capire quali informazioni mancano all'ottimizzatore e fornire statistiche appropriate in modo che possa fare la scelta giusta da sola. Questa è una soluzione molto più stabile in futuro. Sinceramente quando sei ridotto a specificare suggerimenti che coinvolgono più livelli di alias: è troppo facile per qualcuno toccare la definizione della vista per interrompere la query cambiando l'alias del nome della tabella, ad esempio.

+0

+1 Way più completo della risposta che ho appena abbandonato :) Sono anche d'accordo con il consiglio sui suggerimenti di ottimizzazione come ultima risorsa. – APC

+0

Grazie mille, ho la migliore risposta ... Grazie per il tuo aiuto ... Sono davvero sorpreso ...E posso chiederti qualcosa su come approfondire la mia conoscenza dei suggerimenti SQL? Sto cercando un buon tutorial – kupa

+0

E quale è un modo preferibile per identificare quali sqls sono "cattivi" e controllare se l'hai sintonizzato bene ... Come vedo che usi "imposta l'autotrace traceonly"; non usi v $ sql_longops o ADDM? – kupa