Хранятся ли анонимные блоки, проанализированные в SGA? - PullRequest
2 голосов
/ 23 декабря 2009

Я недавно обнаружил, что анонимные блоки можно вызывать из jdbc следующим образом:

    String plsql = "BEGIN" +
                   " :result := foobar( booleanparameter => :mypar > 2);" +
                   "END;";

    con.prepareCall(plsql);

Что здорово, потому что я могу использовать это, чтобы "обернуть" некоторые вызовы функций и преодолеть некоторые ограничения JDBC. Например, я не могу передать логические переменные PL / SQL процедуры, и не может изменить сигнатуру процедур, так как есть много кода, который зависит от них. Добавление новых процедур «обертывания» тоже не легко по причинам внутренней политики.

Так что это кажется приемлемым решением, но я беспокоюсь о разборе накладные расходы. Сохраняются ли анонимные блоки, подобные этому, в SGA или они разбирали каждый раз когда их вызывают?

Спасибо

Обновление 1: Я сделал быстрый скрипт-оболочку для просмотра v $ sqlarea, как предлагает egorius:

String  plsql = "BEGIN :myresult := dbms_random.random ; END;";
OracleDriver oracledrv = new OracleDriver();
Connection   con = oracledrv.connect(connstr, new Properties());

for (int i = 0 ; i < 1000 ; i++ ) {
    CallableStatement cb = con.prepareCall(plsql);
    cb.registerOutParameter("myresult", Types.INTEGER);
    cb.execute();
    System.out.println("random ->" +cb.getInt("myresult"));
    cb.close();
}
con.close();

И вот что я получаю int v $ sqlarea (я запускал его дважды):

SQL_TEXT
--------------------------------------------------------------------------------

PARSE_CALLS EXECUTIONS
----------- ----------
BEGIN :myresult := dbms_random.random ; END;
       2000       2000

Значит ли это, что подготовлен или нет?

Ответы [ 2 ]

5 голосов
/ 23 декабря 2009

Анонимные блоки также кэшируются. Вы можете проверить это, запросив V $ SQLAREA .

SQL> объявить номер abcabc; начать с нуля; конец;
2 /

Процедура PL / SQL успешно завершена.

SQL> /

Процедура PL / SQL успешно завершена.

SQL> select sql_text, выполнение из v $ sqlarea, где sql_text, например '% abcabc%';

SQL_TEXT
-------------------------------------------------- ------------------------------
ИСПОЛНЕНИЕ
----------
объявить номер abcabc; начать с нуля; конец; * * тысяча двадцать-один 2

выберите sql_text, выполнение из v $ sqlarea, где sql_text, например, '% abcabc%'
1

EDIT:

У вас всегда будет так называемая МЯГКАЯ ЧАСТЬ. Это необходимо для синтаксической и семантической проверки запроса. После этого, если точно такой же запрос существует в кеше библиотеки, HARD PARSE будет пропущен. (См. Это Задайте вопрос Тому для хорошего объяснения.)

Вот выдержка из файла трассировки tkprofed 10046:

declare abcabc number; begin null; end;

call     count       cpu    elapsed       disk      query    current        rows  
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.00       0.00          0          0          0           0
Execute      2      0.00       0.00          0          0          0           2
Fetch        0      0.00       0.00          0          0          0           0  
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          0          0           2

Misses in library cache during parse: 1

Последняя строка показывает точку.

1 голос
/ 21 января 2013

Что касается всегда мягкого разбора, это не обязательно так. Oracle позволяет и Java, и PL / SQL иметь возможность анализировать оператор только один раз за сеанс. Это происходит, когда курсор не закрыт, но используется повторно - без разбора. Информация синтаксического анализа SQL: http://docs.oracle.com/cd/E11882_01/server.112/e25789/sqllangu.htm Частная область SQL: http://docs.oracle.com/cd/E11882_01/server.112/e25789/memory.htm#i17716

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...