Funkcja podstawiania SQL w Oracle 10g

9

Trzy lub cztery lata temu przeczytałem gdzieś na blogu Oracle, że DBA użył do rozwiązania incydentu awaryjnego funkcji Oracle 10g zastępowania SQL w czasie rzeczywistym. Zasadniczo skonfigurował Oracle w taki sposób, że za każdym razem, gdy otrzymywał określone zapytanie A, zamiast tego wykonywał kolejne zapytanie B. Bez zmiany kodu aplikacji, bez zmiany schematu, po prostu prosta konfiguracja typu „wykonaj zapytanie B zamiast A”.

Nie dlatego, że planuję użyć tej funkcji (myślę o pewnych niepożądanych konsekwencjach), ale z ciekawości, czy ona naprawdę istnieje? Jeśli tak, jak nazywa się ta funkcja?

Rosół
źródło
Zapisane kontury
Philᵀᴹ
1
@Phil: Myślałem, że zapisane kontury są tylko dla planów wykonania. Czy można je wykorzystać do zastąpienia rzeczywistych zapytań w sposób opisany przez PO?
FrustratedWithFormsDesigner
1
Tak, możesz zmienić tekst SQL za pomocą konturów. Zrobiłem to wcześniej w 9i, aby zmodyfikować zapytanie i dodać kilka wskazówek. To pokazuje, jak to się robi: praktycznyappsdba.wordpress.com/2007/05/18/… - Nie rozumiem, dlaczego nie można zmienić zapytania, dopóki dane wejściowe i wyjściowe pozostają takie same - kontury są oceniane i zastępowane w czasie analizy
Philᵀᴹ
1
Może to być także widok zmaterializowany z włączoną funkcją przepisywania zapytań.
a_horse_w_no_name

Odpowiedzi:

4

To brzmi jak pakiet DBMS_ADVANCED_REWRITE . Tim Hall doskonale posługuje się tym pakietem, aby skierować zapytania aplikacji do innej tabeli lub widoku .

Jeśli chcesz tylko zmienić plan zapytań, ale nie kierujesz zapytania do innej tabeli, możesz użyć zapisanych konturów lub profili SQL.

Na przykład mam tabele FOOz 1 rzędem i BAR2 rzędami

SQL> select * from foo;

      COL1
----------
         1

SQL> select * from bar;

      COL1
----------
        66
        77

Mogę zadeklarować równoważność przepisania, mówiąc, że FOOzamiast tego zapytania powinny trafićBAR

begin
  sys.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE(
    'Rewrite_Foo',
    'select col1 from foo',
    'select col1 from bar',
    false,
    'TEXT_MATCH' );
end;

Teraz, jeśli ustawię query_rewrite_integrityna zaufany, zapytania przeciwko FOOtrafią do zupełnie innej tabeli.

SQL> alter session set query_rewrite_integrity=trusted;

Session altered.

SQL> select * from foo;

      COL1
----------
        66
        77

To może stworzyć dość interesujące plany zapytań, w których nie ma w planach szukanego obiektu

SQL> select * from foo;

      COL1
----------
        66
        77


Execution Plan
----------------------------------------------------------
Plan hash value: 4224476444

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

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        584  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
Justin Cave
źródło