绑定变量窥视cbo的一个附属功能,关闭他不会影响是用cbo还是rbo,就算关闭了绑定变量窥视,cbo还是会利用别的统计信息(num_distinct,density等)来评估cost和cardinality,只
是无法使用直方图信息而已:
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
FROM SYS.x$ksppi x, SYS.x$ksppcv y
WHERE x.inst_id = USERENV ('Instance')
AND y.inst_id = USERENV ('Instance')
AND x.indx = y.indx
AND x.ksppinm LIKE '%&par%'; 2 3 4 5 6
Enter value for par: peek_user
old 6: AND x.ksppinm LIKE '%&par%'
new 6: AND x.ksppinm LIKE '%peek_user%'
NAME VALUE DESCRIB
------------------------------ -------------------- ------------------------------
_optim_peek_user_binds TRUE enable peeking of user binds
此时绑定变量开启:
create table test300 as select * from dba_objects;
SQL> create table test300 as select * from dba_objects;
表已创建。
SQL> create index test300_idx1 on test300(owner);
索引已创建。
SQL> set linesize 200
SQL> /
OWNER COUNT(*)
------------------------------------------------------------------------------------------ ----------
OWBSYS 2
APPQOSSYS 5
SCOTT 6
SI_INFORMTN_SCHEMA 8
BI 8
ORACLE_OCM 8
OUTLN 10
ORDPLUGINS 10
OWBSYS_AUDIT 12
TEST 13
FLOWS_FILES 13
OWNER COUNT(*)
------------------------------------------------------------------------------------------ ----------
HR 34
PM 44
DBSNMP 57
IX 58
OE 142
ORDDATA 257
SH 309
EXFSYS 312
WMSYS 333
CTXSYS 389
SYSTEM 618
OWNER COUNT(*)
------------------------------------------------------------------------------------------ ----------
OLAPSYS 721
XDB 1170
MDSYS 2011
ORDSYS 2513
APEX_030200 2561
SYSMAN 3554
PUBLIC 34001
SYS 37789
已选择30行。
搜集统计信息:
select a.column_name,
b.num_rows,
a.num_distinct Cardinality,
round(a.num_distinct / b.num_rows * 100, 2) selectivity,
a.histogram,
a.num_buckets
from dba_tab_col_statistics a, dba_tables b
where a.owner = b.owner
and a.table_name = b.table_name
and a.owner = 'TEST'
and a.table_name = 'TEST300';
select owner, table_name name, object_type, stale_stats, last_analyzed
from dba_tab_statistics
where table_name in ('TEST300')
and owner = 'TEST'
and (stale_stats = 'YES' or last_analyzed is null);
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'TEST',
tabname => 'TEST300',
estimate_percent => 100,
method_opt => 'for all columns size skewonly',
no_invalidate => FALSE,
degree => 1,
cascade => TRUE);
END;
SQL> alter system flush shared_pool;
System altered.
查看执行计划:
---高级执行计划:
11G:
alter session set statistics_level=all; ---再运行SQL
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
SQL> select * from test300 a where a.owner='TEST';
SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 09j9dupsdynnf, child number 0
-------------------------------------
select * from test300 a where a.owner='TEST'
Plan hash value: 638205358
---------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 13 |00:00:00.23 | 5 | 3 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST300 | 1 | 13 | 13 |00:00:00.23 | 5 | 3 |
|* 2 | INDEX RANGE SCAN | TEST300_IDX1 | 1 | 13 | 13 |00:00:00.01 | 3 | 0 |
---------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OWNER"='TEST')
已选择19行。
select * from test300 a where a.owner='SYS';
SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID d67v6znz35fs2, child number 0
-------------------------------------
select * from test300 a where a.owner='SYS'
Plan hash value: 676079910
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 37789 |00:00:00.04 | 3739 | 1242 |
|* 1 | TABLE ACCESS FULL| TEST300 | 1 | 37789 | 37789 |00:00:00.04 | 3739 | 1242 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"."OWNER"='SYS')
已选择18行。
使用绑定变量进行测试:
alter session set statistics_level=all;
SQL> set linesize 200
SQL> set pagesize 200
SQL> variable n varchar2(10);
SQL> exec :n :='TEST';
PL/SQL 过程已成功完成。
SQL> select * from test300 where owner = :n;
已解释。
已选择13行。
SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID c5aj1qt7aqw6w, child number 1
-------------------------------------
select * from test300 where owner = :n
Plan hash value: 638205358
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 13 |00:00:00.01 | 5 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST300 | 1 | 13 | 13 |00:00:00.01 | 5 |
|* 2 | INDEX RANGE SCAN | TEST300_IDX1 | 1 | 13 | 13 |00:00:00.01 | 3 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER"=:N)
已选择19行。
SQL> exec :n :='SYS';
PL/SQL 过程已成功完成。
SQL>select * from test300 where owner = :n;
已解释。
SQL>
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));SQL>
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID c5aj1qt7aqw6w, child number 1
-------------------------------------
select * from test300 where owner = :n
Plan hash value: 638205358
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 37789 |00:00:00.07 | 6049 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST300 | 1 | 13 | 37789 |00:00:00.07 | 6049 |
|* 2 | INDEX RANGE SCAN | TEST300_IDX1 | 1 | 13 | 37789 |00:00:00.03 | 2596 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER"=:N)
已选择19行。