【《TOP》读书笔记】<2> Key Concepts

这一章主要介绍整本书的一些概念性的词句。

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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值