Mittwoch, Februar 29, 2012

Explain Plan für Remote-Zugriffe

Es gibt bekanntlich eine ganze Reihe von Gründen dafür, den Aussagen von Explain Plan mit einem leichten Misstrauen zu begegnen, da sie nicht immer so ganz den Tatsachen der tatsächlichen Ausführung einer Query entsprechen. Trotzdem verwende ich Explain Plan gerne, um eine Vorstellung vom wahrscheinlichen Ausführungsplan zu bekommen, vor allem dann, wenn meine Queries keine Bind-Variablen enthalten. Zur Anzeige der Pläne verwende ich dann normalerweise dbms_xplan.display. Aber offenbar gibt es Fälle, in denen diese nützliche table function nicht tut, was ich von ihr erwarte. Ein solches Beispiel betrifft den Remote-Zugriffe via DB-Link. Dazu ein kleiner Test:

Gegeben ist eine Datenbank der Version 11.1.0.7, in der database links auf mehrere ältere Datenbank definiert sind. Zunächst ein lokaler Zugriff:

-- Explain für einen lokalen Zugriff auf dual:
explain plan for select * from dual;

EXPLAIN PLAN ausgeführt.

select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
Plan hash value: 272002086

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

Jetzt ein Zugriff auf eine zweite Datenbank der Version 10.2.0.4:

-- Explain für einen remote-Zugriff auf dual in einer DB 10.2.0.4:
explain plan for select * from dual@db_10;

EXPLAIN PLAN ausgeführt.

select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 272002086

----------------------------------------------------------------------------------------
| Id  | Operation              | Name | Rows  | Bytes | Cost (%CPU)| Time     | Inst   |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT REMOTE|      |     1 |     2 |     2   (0)| 00:00:01 |        |
|   1 |  TABLE ACCESS FULL     | DUAL |     1 |     2 |     2   (0)| 00:00:01 |  DB_10 |
----------------------------------------------------------------------------------------

Note
-----
   - fully remote statement

Nun zum interessanten Fall des Zugriffs auf eine DB 9.2.0.6

-- Explain für einen remote-Zugriff auf dual in einer DB 9.2.0.6:
explain plan for select * from dual@db_9;

EXPLAIN PLAN ausgeführt.

select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
-----------------------------------------------------
Error: cannot fetch last explain plan from PLAN_TABLE

Ursache der Meldung ist aber offenbar nicht das Fehlen von Angaben in der plan_table:

select PLAN_ID, OPERATION, OPTIONS, OBJECT_NAME from plan_table;

PLAN_ID OPERATION                      OPTIONS                        OBJECT_NAME
------- ------------------------------ ------------------------------ -----------
        SELECT STATEMENT               REMOTE
        TABLE ACCESS                   FULL                           DUAL

Verantwortlich für das Verhalten ist die PLAN_ID, die nur für die Ausführung der Query in der 9er Datenbank NULL ist, aber in den neueren DBs einen numerischen Wert enthält. In Ermanglung von SQL-Trace basiert diese Aussage auf folgendem Test:

-- im Fall der DB 9.2.0.6:
update plan_table set PLAN_ID = 4711 where PLAN_ID is null;

2 Zeilen wurden aktualisiert.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
------------------------------------------------

------------------------------------------------
| Id  | Operation              | Name | Inst   |
------------------------------------------------
|   0 | SELECT STATEMENT REMOTE|      |        |
|   1 | TABLE ACCESS FULL      | DUAL |   DB_9 |
------------------------------------------------

Note
-----
   - fully remote statement


Im denke nicht, dass man in der plan_table mit einem solchen Update viel kaputt machen kann, würde aber vermutlich für die Auswertung dann doch eher auf eine traditionelle Auswertungs-Query zurückgehen.


Keine Kommentare:

Kommentar veröffentlichen