2010-11-19 4 views
10

私はビューを持っていて、そのようなビューをクエリしてベーステーブルのインデックスをヒントしたいのですが、それを行うことはできますか?ビューにヒントを使用しますか?

私は意味:

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

は、私が " index1の" と呼ばれるインデックスにtable1.col1を持っています。

...

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

そして、私はこのクエリの実行計画を見ると、それは「index1の」を使用していない私にそのクエリを示しており、私はそれを示したい:

私はクエリを持っています

だから私はそれが欲しい、例えば:

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

私はビューのヒントを示すことができますか? (このビューの作成時に表示しない場合)

+0

私はこれを意味する/ * + index(temp_view index1)* /動作しません。ヒントを示すために他の方法を知りたいので、これをここに書いていますこのビューは別のユーザーによって作成されたものであり、ビューを変更するのは適切ではないため、ビューを変更したくありません。 – kupa

+0

と私が尋ねたいもう1つのこと...ヒントによってクエリを最適化する方法についての良い知識を与える役に立つチュートリアルを知っていますか?してください – kupa

+0

@ACPあなたは何を編集しましたか? :D:D私の投稿にはエディションが見つかりませんでした:D – kupa

答えて

12

ビューに対する問合せでヒントを使用して、Oracleにベース表の索引を使用させることができます。しかし、基になるビュー内のベーステーブルのエイリアス(存在する場合)を知る必要があります。一般的な構文は、10,000同じ行のテーブルを作成し、テーブルにインデックスを作成する)/*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

1であろう。 Oracleは、それが

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)インデックスが正常に使用されていないことを確認し使用したくありませんので、インデックスは、選択されませんが、Oracleは、ヒント

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)ビューを作成します。 、ビューに対する通常のクエリがインデックスを使用していないことを確認しますが、ビューの定義

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> 

からしかし、言ったことすべてをクエリ内のビューの別名と表の別名の両方を指定することにより、使用するインデックスを強制ヒントは一般的に問合せを調整しようとする最後の手段です。オプティマイザが失う情報を把握し、適切な統計を提供して正しい選択を行うことが一般的にははるかに好ましい方法です。それは今後さらに安定した解決策です。恐らく、別名の複数のレイヤーを含むヒントを指定することに減らされたときには、ビュー定義に触れることでテーブル名のエイリアスを変更するなどしてクエリを壊すのは簡単すぎます。

+0

+1私が放棄した答えよりも包括的な方法:最後の手段としてヒントを調整する方法についてのアドバイスに同意します。 – APC

+0

大変ありがとうございます。最高の答えを...ありがとうございました。あなたのご協力ありがとうございます...私は本当に驚いています...そして、SQLヒントについての私の知識を深める方法について何かお尋ねすることができますか?私は良いチュートリアルを探しています – kupa

+0

そして、どのsqlsが "悪い"ものであるかを特定し、それをうまく調整したかどうかを確認するための好ましい方法は何ですか... "autotrace traceonly; v $ sql_longopsまたはADDMを使用しないでください。 – kupa

関連する問題