powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / как избежать парсинга?
2 сообщений из 2, страница 1 из 1
как избежать парсинга?
    #32167536
mutate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
oracle 9.2.0.2 под Linux RH AS 2.1

имеем небольшой программ для теста:

DECLARE
cursor crs is select c_doc from z#records where rownum <= 100;
sql_stmt VARCHAR2(200);
i_ varchar2(32);
BEGIN
for i in crs loop
sql_stmt := 'select id from z#document where id='||i.c_doc;
EXECUTE IMMEDIATE sql_stmt INTO i_;
dbms_output.put_line('i_>'||i_);
end loop;
END;

параметер cursor_sharing выставим в EXACT, и натравим на это дело tkprof, то видим что 100 раз будет выполняться подобное: (с конкретным ID)

select id
from
z#document where id=256216981

call count cpu elapsed
------- ------ -------- ----------
Parse 2 0.00 0.00
Execute 2 0.00 0.00
Fetch 2 0.00 0.00
------- ------ -------- ----------
total 6 0.00 0.00


если параметер cursor_sharing выставим в FORCE, имеем такой результат:

select id
from
z#document where id=:"SYS_B_0"

call count cpu elapsed
------- ------ -------- ----------
Parse 100 0.00 0.06
Execute 100 0.00 0.01
Fetch 100 0.00 0.00
------- ------ -------- ----------
total 300 0.00 0.09

видно что появилась bind переменная "SYS_B_0", однако общее количество парсинга этого запроса осталось равным 100.. То есть все равно он парсит этот запрос 100 раз.. Какой смысл в этом? Что я упускаю?
...
Рейтинг: 0 / 0
как избежать парсинга?
    #32168145
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
First of all, you are littering shared pool. Every time Oracle needs to parse a cursor it searches shared pool for an either exact match (CURSOR_SHARING=EXACT) or almost (up to some literals) exact match (CURSOR_SHARING=FORCE). By constructing SQL as:

Код: plaintext
sql_stmt := 'select id from z#document where id='||i.c_doc;

in a loop, you are adding a 100 SQL statements (your loop has 100 iterations) to shared pool. If CURSOR_SHARING=EXACT, Nth iteration of the loop will look at N-1 SQL statements already it shared pool (I assume, for simplicity, shared pool is empty before script starts) and will not have a match (assuming all iterations return different c_doc values). Then Oracle will hard parse the statement and add it to shared pool. If CURSOR_SHARING=FORCE, SQL issued by iterations 2 to 100 will be matched to SQL issued by first iteration, but at a cost of much more complex matching rules comparing to exact matching. As a result, it will avoid hard parsing, which still takes more resources than forced matching, but still will cost you. To avoid forced matching, you should use bind variables:

Код: plaintext
sql_stmt := 'select id from z#document where id=:1'


and then specify USING i.c_doc in EXECUTE IMMEDIATE. This way, regardless of CURSOR_SHARING=EXACT or FORCE, Oracle will do soft parse for iterations 2 through 100 without waisting additional resources on forced matching and only one SQL statement will end up in shared pool . However, it still will not avoid parsing 100 times, but rather minimize parse time. To parse once, you should use DBMS_SQL, since it is the only way in PL/SQL I know where you can specify PARSE and EXECUTE in separate calls. PL/SQL statements OPEN, OPEN FOR, EXECUTE IMMEDIATE, FOR LOOP, etc. perform both PARSE and EXECUTE. Usind DBMS_SQL, you could place DBMS_SQL.PARSE before FOR LOOP and thus parsing one time only.

SY.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / как избежать парсинга?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]