一:parent cursor与child cursor得区别 联系
SQL> ALTER SESSION SET optimizer_mode = all_rows;
SQL> SELECT count(*) FROM t;
SQL> ALTER SESSION SET optimizer_mode = first_rows_10;
SQL> SELECT count(*) FROM t;
The result is that a single parent cursor (5tjqf7sx5dzmj) and two child cursors (0 and 1) are
created.
parent cursor:10g中v$sql,v$sqlarea的sql_id代表一个parent cursor.
child cursors:child_number代表一个child cursors,plan_hash_value代表相同的执行计划
user global area (UGA):存储指向SHARE POOL中child cursors的指针。
对相同的parent cursor(相同SQLTEXT)如果有不同的执行计划或者运行环境就产生不同的child cursors,最少含有一个child cursors(child_number=0);
实际中 parent cursor 不能共享的情况比child cursors多(比如上面的例子中改变优化模式导致),原因大多为SQL TEXT修改或者使用动态SQL(没有绑定变量解决)
查找没有共享的SQL:
SELECT sql_id, child_number, executions
FROM v$sql where child_number>0
查找没有共享的原因:没有绑定变量(Y)
SQL> SELECT child_number, bind_mismatch
2 FROM v$sql_shared_cursor
3 WHERE sql_id = '6cvmu7dwnvxwj';
CHILD_NUMBER BIND_MISMATCH
------------ -------------
0 N
1 Y
二:绑定变量对优化器的影响:
优化器不知道变量具体值 不能正确的选择执行计划
E。G
SQL> SELECT count(id), count(DISTINCT id), min(id), max(id) FROM t;
COUNT(ID) COUNT(DISTINCTID) MIN(ID) MAX(ID)
---------- ----------------- ---------- ----------
1000 1000 1 1000
以下2个语句有着不同的执行计划,但是优化器会一直走第一个SQL的执行计划
SQL> SELECT count(pad) FROM t WHERE id < 990;
COUNT(PAD)
----------
989
SQL> SELECT count(pad) FROM t WHERE id < 10;
COUNT(PAD)
----------
9
使用绑定变量注意:
1:不带WHERE 的SQL 必须使用绑定变量 (INSERT UPDATE。。)
2:处理小量数据使用绑定变量。当解析时间和处理时间几乎相同的使用,比如 OLTP SYSTEM
3:处理大量数据不要使用绑定变量。解析时间一般都是处理时间的好几倍绑定变量会不利于优化器产生高效的执行计划。需要找到一个解析和处理SQL时间的平衡点。