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.
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
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
@ACP was hast du bearbeitet ?? : D: D Ich habe keine Ausgabe in meinem Beitrag gefunden: D – kupa