Oracle 9.2; Indices/Index auf view geht das?

tplanitz

Erfahrenes Mitglied
Hallo,

bei Abfragen die einen View benutzen ergibt sich nach meiner Wahrnehmung ein erheblicher Performance einbruch.
Weiß jemand von Euch ob man auf einen View Indices anlegen kann
Ich stelle mir das so vor
PHP:
Create Index idx_on_view on v_my_view (a_attribut1, a_attribut2)

Habs bei Oracle probiert und bekomme die Fehlermeldung:
PHP:
ORA-01702: a view is not appropriate here
 
Ersteinmal vorweg: Auf eine View kann man keinen Index legen. Kann auch gar nicht funktionieren, weil eine View keine Physikalischen Daten enthält. Wie der Name schon sagt ist eine View lediglich eine andere "Sicht" auf Daten, sprich Tabellen. Für eine Datenbank bedeutet dies: Nimm das SQL Statement, dass der View zu Grunde liegt, kombiniere es mit dem SQL Statement, dass der Benutzer an die View gegeben hat und selektiere die beteiligten Tabellen.

Beispiel:
SQL:
CREATE OR REPLACE VIEW myView1
AS
SELECT	*
FROM		myTable
WHERE		category = 3;
/

SELECT 	* 
FROM		myView1
WHERE		ID = 15;

Daraus baut Oracle automatisch:

SELECT	*
FROM		myTable
WHERE		category = 3
AND		ID			= 15;

D.h. in diesem Fall würde uns ein Index über die Spalten category oder ID der Tabelle myTable helfen. Die Tatsache, dass dir Views langsamer vorkommen kann nur daran liegen, dass die Statements aus denen sich die View aufbaut oft komplex sind und eben nicht nur ein SELECT * FROM TABLE. Würde man das Statement der View direkt an die Datenbank schicken wäre es ebenso schlecht, und sogar noch schlechter. Grund hierfür ist, dass die Statements in der View von der Datenbank schon geparst vorliegen und somit schneller ausgeführt werden können, d.h. es liegen zum Teil schon gute Ausführungspläne für Anfragen vor.

Beweis bringt der EXPLAIN PLAN
Code:
SQL> select * from test;

TEXT
--------------------------------------------------
Text1
Text2

SQL> create or replace view v_test as select * from test;

View wurde erstellt.

SQL> select * from test;

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    12 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| TEST |     2 |    12 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

SQL> select * from v_test;

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    12 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| TEST |     2 |    12 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Man sieht, es wird zweimal die gleiche Tabelle mit exakt gleichen kosten gelesen. Wenn Views also extrem langsam sind gibts nur eine Möglichkeit: Das Statement der View analysieren und gezielt optimieren. Entweder Statement umstellen oder Indizes auf Tabellen.
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

vielen Dank für Eure ausführlichen Hinweise, ich komme wohl nicht drum herum den View zu analysieren und die Indizes auf die abgefrageten tabellen geschickt anzulegen.

btw noch eine Frage -> kann man aus einem bestehenden materialized view weitere materialized view erstellen

Viele Grüße
 
Zurück