绑定变量窥测(Bind Variable Peeking)
绑定变量窥测是oracle在进行硬解析生成执行计划的时候会窥探绑定变量的真实值,去评估绑定变量的谓词条件的选择率,影响执行计划是选择访问路径是先走索引扫描进而去访问表还是直接走全表扫描。
没有绑定变量窥测这一特性的时候oracle怎么去评估选择性那,是基于字段统计信息中ndv,ndv接近表的行数的时候,选择性越高,走索引的概率越大,ndv越小,则选择性越差,走全表扫描的概率也就越大,但是在真实环境中,很多业务场景中字段取值都不均匀的,这个时候使用ndv去评估选择性显然不合理,所以绑定变量窥测会参考字段的取值,字段直方图等统计信息,会评估出一个可靠的选择率,这个时候优化器再去做选择就准确多了。
绑定变量窥测的好处是能够准确的生成第一次语句执行的时候的执行计划,但是由于游标共享,之后相同的语句再次执行的时候不会再去窥探,这个是使用绑定变量的一个不好之处。
绑定变量窥测在oracle 9i中被引入,受到隐藏参数_optim_peek_user_binds的控制,并且该参数的默认值是true,就是说,绑定变量窥测这一特性默认是启用的。
优化器是否使用绑定变量窥测去生成执行计划那,可以打印cursor中的执行计划观察这一特性的作用。
1 select * from table(dbms_xplan.display_cursor('d0g5mw5skptkq',0,'allstats advanced last')); 2 3 SQL_ID d0g5mw5skptkq, child number 0 4 ------------------------------------- 5 select * from t1 where owner = :owner 6 7 Plan hash value: 3617692013 8 9 --------------------------------------------------------------------------- 10 | Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | 11 --------------------------------------------------------------------------- 12 | 0 | SELECT STATEMENT | | | | 427 (100)| | 13 |* 1 | TABLE ACCESS FULL| T1 | 90944 | 9M| 427 (1)| 00:00:01 | 14 --------------------------------------------------------------------------- 15 16 Query Block Name / Object Alias (identified by operation id): 17 ------------------------------------------------------------- 18 - SEL$1 / T1@SEL$1 19 Peeked Binds (identified by position): 20 -------------------------------------- 21 - :1 (VARCHAR2(30), CSID=178): 'SYS' 22 23 Predicate Information (identified by operation id): 24 --------------------------------------------------- 25 - filter("OWNER"=:OWNER)
执行计划的黄色部分所以,oracle在生成此执行计划的时候,用到了绑定变量窥测,由于‘SYS’在列中的选择率太低,所以优化器选择走全表扫描的表访问路径。