2010-11-19 19 views
10

Ich habe eine Sicht und möchte meine Sicht so abfragen, um einen Index aus einer Basistabelle anzudeuten, kann ich das tun?Tipps für Aufrufe verwenden?

ich meine:

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

Ich habe einen Index auf table1.col1 genannt "index1".

Ich habe eine Abfrage:

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

Und wenn ich Plan dieser Abfrage erklären sehen, es zeigt mir, dass die Abfrage nicht „index1“ nicht verwendet und ich möchte es zeigen ..

So mag ich es zum Beispiel sein,:

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

Kann ich Hinweise für Ansichten anzeigen ?? (Wenn ich dies während der Erstellung dieser Ansicht nicht anzeigen möchte)

+0

Ich habe getestet und es funktioniert nicht ich meine das/* + index (temp_view index1) */funktioniert nicht..Ich habe dies hier geschrieben, weil ich einen anderen Weg wissen möchte, wenn es gibt Hinweis anzuzeigen für Ansichten..Ich möchte die Ansicht nicht ändern, da diese Ansicht von einem anderen Benutzer erstellt wird und es nicht richtig ist, ihre Ansicht zu ändern. – kupa

+0

und noch eine Sache, die ich fragen möchte ... Kennen Sie einige nützliche Tutorials, die mir ein gutes Wissen darüber geben, wie man Abfragen durch Hinweise optimieren kann? bitte – kupa

+0

@ACP was hast du bearbeitet ?? : D: D Ich habe keine Ausgabe in meinem Beitrag gefunden: D – kupa

Antwort

12

Sie können einen Hinweis auf eine Abfrage für eine Sicht verwenden, um Oracle zur Verwendung eines Index für die Basistabelle zu zwingen. Sie müssen jedoch den Alias ​​der Basistabelle (falls vorhanden) in der zugrunde liegenden Sicht kennen. Die allgemeine Syntax wäre /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

Ein Beispiel

1) Erstellen einer Tabelle mit 10.000 identischen Zeilen und einen Index für die Tabelle erstellen. Der Index wird nicht selektiv sein, so Oracle wird es nicht überprüfen:

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) verwendet werden soll, dass der Index nicht normalerweise verwendet wird, sondern dass Oracle wird es mit einem

Hinweis verwendet
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) Erstellen Sie nun die Ansicht. Stellen Sie sicher, dass normale Abfragen für die Ansicht den Index nicht verwenden, aber den Index zu zwingen sowohl durch Angabe verwendet werden, um die Ansicht alias in der Abfrage und die Tabelle alias aus der Sicht Definition

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> 

Alles, was gesagt, aber Hinweise im Allgemeinen sind ein letzter Ausweg, wenn Sie versuchen, eine Abfrage zu optimieren - es ist im Allgemeinen weit vorzuziehen, herauszufinden, welche Informationen der Optimierer nicht enthält, und entsprechende Statistiken bereitzustellen, damit er die richtige Entscheidung treffen kann. Das ist eine viel stabilere Lösung für die Zukunft. Zweifellos, wenn Sie darauf beschränkt sind, Hinweise anzugeben, die mehrere Ebenen von Aliasen umfassen, ist es für jemanden, der die Sichtdefinition berührt, viel zu einfach, die Abfrage zu unterbrechen, indem beispielsweise der Alias ​​des Tabellennamens geändert wird.

+0

+1 Weg umfassender als die Antwort, die ich gerade aufgegeben habe :) Ich stimme auch mit dem Rat über Tuning Hinweise als letzter Ausweg. – APC

+0

Vielen Dank Ich habe die beste Antwort ... Danke für Ihre Hilfe ... Ich bin wirklich überrascht ...Und kann ich dich etwas fragen, wie ich mein Wissen über SQL-Tipps vertiefen kann? Ich bin auf der Suche nach einem guten Tutorial – kupa

+0

Und was ist ein bevorzugter Weg zu identifizieren, welche sqls "schlecht" sind und prüfen, ob Sie es gut abgestimmt haben ... Wie ich sehe, verwenden Sie "set autotrace traceonly;" Verwenden Sie nicht v $ sql_longops oder ADDM? – kupa