|
|
|
как избежать парсинга?
|
|||
|---|---|---|---|
|
#18+
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 раз.. Какой смысл в этом? Что я упускаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2003, 16:54:27 |
|
||
|
как избежать парсинга?
|
|||
|---|---|---|---|
|
#18+
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 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 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2003, 23:04:04 |
|
||
|
|

start [/forum/topic.php?fid=52&fpage=2774&tid=1990369]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
58ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
30ms |
get tp. blocked users: |
1ms |
| others: | 202ms |
| total: | 331ms |

| 0 / 0 |
