这一章主要介绍整本书的一些概念性的词句。
1.Selectivity and Cardinality
cardinality = selectivity . num_rows
2.Life Cycle of a Cursor
Open cursor
Parse cursor
Define output variables
Bind input variables
Execute cursor
Fetch cursor
Close cursor
3.Parse的各个步骤
Include VPD predicates:其实就是如果有行级的安全策略,那么会有这一步产生的谓词加入where条件里。
Check syntax, semantics, and access rights:语法语义和权限的检查。
Store parent cursor in library cache:常常第一次执行时,连parent cursor都不在shared pool里面,就要在library cache里分配空间。此时决定一个parent cursor最重要的就是sqltext。
Logical optimization:就是再考虑一下SQL transformation所产生的更多可能的执行计划。
Physical optimization:优化器选择出最优的执行计划,如果使用的是CBO,就根据对每种可能的执行计划算出其cost,取其最小者。
Store child cursor in library cache:将child cursor存入shared pool的library cache中。child cursor最重要的就是执行计划和执行环境。
接着,parent cursor可以通过v$sqlarea中查找,child cursor可以使用v$sql。
例如,我在一个测试库里看到v$sqlarea并不包括所有的cursors,如果通过version_count字段可以得出大部分和v$sql是相同的,但是有一点mismatch,至于为什么,我也不知道。
SQL> select count(distinct SQL_ID),count(*) from v$sql;
COUNT(DISTINCTSQL_ID) COUNT(*)
--------------------- ----------
2352 5466
SQL> select count(distinct SQL_ID),count(*),sum(VERSION_COUNT) from v$sqlarea;
COUNT(DISTINCTSQL_ID) COUNT(*) SUM(VERSION_COUNT)
--------------------- ---------- ------------------
2352 2352 5506
soft parse就是指只有前两步执行。
hard parse就是指以上所有步骤都执行。
4.Shareable Cursors
parent cursor无法share常常是因为sqltext更改,例如literal sql。
child cursor无法share由两种情况:1,执行计划变了,2,执行的环境变了。
书中给出了个例子是在session级别更改了optimizer_mode,虽然执行计划相同,但是还是产生了不同的child cursors(v$sql_shared_cursor.OPTIMIZER_MODE_MISMATCH不一样)。
其实只要更改任意一个优化器的参数,也都类似,此时的表现是v$sql_shared_cursor.OPTIMIZER_MISMATCH不一样。
有兴趣的同学可以对v$sql_shared_cursor的每一列不一致的情况做个测试总结。
5.用bind variable的优点与bind variable graduation
当然是减少hard parses和节约shared pool的内存空间。
但是也有可能即使使用了bind variable,还是无法共享child cursor的情况,那就是绑定变量为varchar2字段时,其最大值不一致时。
这个问题最近在我们的生产库上出现了,很是头疼,一个办法是让开发人员将所有的varchar2绑定变量都使用最大值为varchar2(4000)。
因为varchar2变量会根据其最大长度分成4种情况(bind variable graduation),如果你的SQL里有10个varchar2的绑定变量,而且实际绑定的值的长度会不断变化,那么最多会产生4的十次方个child cursors。
这里我show一个我们的产生巨多的child cursors的SQL:
> select sql_id,version_count from v$sqlarea
2 where version_count>100
3 order by version_count desc;
SQL_ID VERSION_COUNT
------------- -------------
xxx 7576
SELECT
distinct(m.max_length)
FROM v$sql s, v$sql_bind_metadata m
WHERE s.sql_id = 'xxx'
AND s.child_address = m.address
AND (m.datatype=1);
MAX_LENGTH
----------
32
128
2000
4000
如上通过查看v$sql_bind_metadata我们可以看出varchar2字段(即datatype=1)的四种分类的界限分别是32,128,2000和4000。
6.用bind variable的缺点与bind variable peeking
缺点当然是优化器看不到绑定的值,所以只有估算,有时无法得到最优的执行计划,尤其是数据倾斜时。
bind variable peeking就是为了解决这个问题而在9i时引入的。但是此feature只会抓取第一次hard parse时的变量值来产生执行计划,一次生成,一直使用。
extended cursor sharing(aks adaptive cursor sharing)这个11G new feature孕育而生,使得不同绑定变量值产生不同的执行计划。
11G的ACS可以看我这篇文章详细介绍:
http://space.itpub.net/15415488/viewspace-621535
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15415488/viewspace-672667/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15415488/viewspace-672667/