2010-11-19 61 views
10

我有一個視圖,我想查詢我的視圖,從基表提示一些索引,我可以這樣做嗎?使用提示的意見?

我的意思是:

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

我有table1.col1指數稱爲 「索引1」。

我有一個查詢

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

當我看到這個解釋查詢計劃它表明我查詢不使用「指數1」,我想表明它..

所以,我希望它是,例如:

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

我可以指示意見的提示? (如果我不想在創建此視圖時指明它)

+0

我測試過了,它不起作用我的意思是這個/ * +索引(temp_view index1)* /不起作用。我在這裏寫了這個,因爲我想知道任何其他方式,如果存在以指示提示對於views..I我不想改變視圖,因爲這個視圖是由另一個用戶創建的,並且改變她的視圖是不正確的。 – kupa 2010-11-19 05:59:55

+0

以及我想問的另外一件事...你知道一些有用的教程,它們會給我一個很好的關於如何通過提示優化查詢的知識嗎?請 – kupa 2010-11-19 06:01:03

+0

@ACP你編輯了什麼? :D:D我在我的帖子中找不到任何版本:D – kupa 2010-11-19 06:47:23

回答

12

您可以對查詢使用提示來強制Oracle在基表上使用索引。但是你需要知道底層視圖中基表的別名(如果有的話)。一般語法將/*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

一個例子

1)創建10,000相同行的表,並在表上創建的索引。該指數將不會有選擇性的,所以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 2010-11-19 06:35:14

+0

非常感謝你我已經得到了最好的答案......謝謝你的幫助......我真的很驚訝......我可以問你一些關於如何深入瞭解關於sql提示的知識嗎?我正在尋找一個很好的教程 – kupa 2010-11-19 06:44:21

+0

什麼是最好的方法來確定哪些sqls是「壞」,並檢查你是否調整好了......當我看到你使用「set autotrace traceonly;」你不使用v $ sql_longops或ADDM? – kupa 2010-11-19 07:54:58