DBMS_ADVANCED_REWRITE

Imagine que um desenvolvedor fez esta obra de arte na aplicação:

SQL> ALTER SESSION SET OPTIMIZER_MODE=RULE;

SessÒo alterada.

SQL> SET TIMING ON;
SQL> SELECT /*+ INDEX(T_ALIAS,IDX_T) */ COUNT(*) FROM T T_ALIAS WHERE OBJECT_NAME = ‘T’;

COUNT(*)
———-
64

Decorrido: 00:00:56.62

Neste SELECT, um índice está sendo utilizado forçadamente quando um Full Table Scan seria mais rápido.

Analisando o SELECT, você ve que uma consulta sem o HINT realmente é muito mais rápida:

SQL> SELECT COUNT(*) FROM T T_ALIAS WHERE OBJECT_NAME = ‘T’;

COUNT(OBJECT_NAME)
——————
64

Decorrido: 00:00:07.75

Mas o problema é que o desenvolvedor não concorda, ou a aplicação é fechada, e o SELECT não pode ser alterado.

Sem problemas ! A partir do 10g, você tem controle completo sobre os comandos SQLs executados no Banco de Dados, utilizando a Package DBMS_ADVANCED_REWRITE.

Nesta Package, você escolhe um SOURCE_STMT e um DESTINATION_STMT: sempre que um SQL igual ao SOURCE_STMT for executado, ele será trocado pelo DESTINATION_STMT.

SQL> BEGIN
2    SYS.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE (
3       NAME             => ‘PORTILHO_REWRITE’,
4       SOURCE_STMT      => ‘SELECT /*+ INDEX(T_ALIAS,IDX_T) */ COUNT(*) FROM T T_ALIAS WHERE OBJECT_NAME = ”T”’,
5       DESTINATION_STMT => ‘SELECT COUNT(*) FROM T T_ALIAS WHERE OBJECT_NAME = ”T”’,
6       VALIDATE         => FALSE,
7       REWRITE_MODE     => ‘TEXT_MATCH’);
8  END;
9  /

Procedimento PL/SQL concluÝdo com sucesso.

Decorrido: 00:00:00.70
SQL> SELECT /*+ INDEX(T_ALIAS,IDX_T) */ COUNT(*) FROM T T_ALIAS WHERE OBJECT_NAME = ‘T’;

COUNT(*)
———-
64

Decorrido: 00:00:07.90

Voilá. O tempo ficou muito melhor, o SQL foi reescrito, e o desenvolvedor nem sabe disso.

2 comments

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.