2010-11-19 5 views
10

J'ai une vue et je veux interroger ma vue comme ça pour faire allusion à un index d'une table de base, est-ce que je peux le faire?Utilisez les astuces pour les vues?

Je veux dire:

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

J'ai un indice sur table1.col1 appelé "index1".

J'ai une requête :

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

Et quand je vois expliquer le plan de cette requête, il me montre que la requête ne pas utiliser « index1 » et je veux indiquer ..

Je veux que ce soit, par exemple:

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

Puis-je indiquer des notes pour les vues ?? (Si je ne veux pas l'indiquer lors de la création de cette vue)

+0

J'ai testé et cela ne fonctionne pas Je veux dire ceci/* + index (temp_view index1) */ne fonctionne pas .. J'ai écrit ceci ici parce que je veux savoir d'une autre manière s'il existe pour indiquer l'indice pour les vues ... Je ne veux pas changer de vue car cette vue est créée par un autre utilisateur et il n'est pas correct de changer sa vue. – kupa

+0

et encore une chose que je veux demander ... Connaissez-vous quelques tutoriels utiles qui me donneront une bonne connaissance sur la façon d'optimiser les requêtes par astuces? s'il vous plaît – kupa

+0

@ACP qu'avez-vous édité ?? : D: D Je n'ai trouvé aucune édition dans mon message: D – kupa

Répondre

12

Vous pouvez utiliser un indice dans une requête sur une vue pour forcer Oracle à utiliser un index sur la table de base. Mais vous devez connaître l'alias de la table de base (le cas échéant) dans la vue sous-jacente. La syntaxe générale serait /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

Un exemple

1) Créer une table avec 10.000 lignes identiques et créer un index sur la table. L'indice ne sera pas sélective, donc Oracle ne voudra pas utiliser

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) Vérifiez que l'index n'est pas utilisé normalement, mais que Oracle va l'utiliser avec un soupçon

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) Créez maintenant la vue. Vérifiez que les requêtes normales contre le point de vue de ne pas utiliser l'index, mais forcer l'index à utiliser en spécifiant à la fois l'alias de vue dans la requête et l'alias de table de la définition de vue

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> 

Tout cela étant dit, cependant, Les astuces en général sont un dernier recours lorsque vous essayez de régler une requête. En général, il est préférable de savoir quelles sont les informations manquantes de l'optimiseur et de fournir des statistiques appropriées pour qu'il puisse faire le bon choix tout seul. C'est une solution beaucoup plus stable pour l'avenir. Doublement, lorsque vous êtes réduit à spécifier des indices qui impliquent plusieurs couches d'alias - il est trop facile pour quelqu'un qui touche la définition de la vue de casser votre requête en changeant l'alias du nom de la table, par exemple.

+0

+1 Way plus complet que la réponse que je viens d'abandonner :) Je suis également d'accord avec les conseils sur les conseils de réglage en dernier recours. – APC

+0

Merci beaucoup J'ai la meilleure réponse ... Merci pour votre aide ... Je suis vraiment surpris ...Et puis-je vous demander quelque chose sur la façon d'approfondir mes connaissances sur les conseils sql? Je cherche un bon tutoriel – kupa

+0

Et quel est un moyen préférable d'identifier quels sqls sont "mauvais" et vérifiez si vous l'avez bien réglé ... Comme je le vois vous utilisez "set autotrace traceonly;" n'utilisez-vous pas v $ sql_longops ou ADDM? – kupa

Questions connexes