关于动态抽样(DynamicSampling)(二)

2015-01-27 22:37:29 · 作者: · 浏览: 72
等;
3)单独索引,聚集因素,叶子块数量,索引高度等。


但注意这里面缺少了某些关键统计信息,例如表中不同列数据之间的关联!
假设你你有一个全球人口普查表!
一个属性是:出生月份MONTH_BORN_IN,另一个属性是:所属星座ZODIAC_SIGN。收集信息后,你问优化器出生在11月份的人数?
假设12个月人数正常分布,那么优化器很快给出答案是全量数据的1/12!再问一个:星座是双鱼座的人数呢?答案也是1/12!
迄今为止优化器对答如流!!!nice work!
但是第3个问题来了:出生在11月份并且星座是双鱼座的人数是多少呢?
明眼人转下脑子就知道答案是0(双鱼座2月19日-3月20日)!但是我们看优化器的答案:1/12/12!!! 多么异想天开的答案,思维定式!这样就会诞生差的执行计划,
也正是在此时我们的动态采样开始干预:


code4: 创建模拟数据
SQL > create table t
as select decode( mod(rownum,2), 0, 'N', 'Y' ) flag1,
decode( mod(rownum,2), 0, 'Y', 'N' ) flag2, a.*
from all_objects a
/
Table created.


SQL > create index t_idx on t(flag1,flag2);
Index created.


SQL > begin
dbms_stats.gather_table_stats
( user, 'T',
method_opt=>'for all indexed columns size 254' );
end;
/
PL/SQL procedure successfully completed.


SQL> select num_rows, num_rows/2,
num_rows/2/2 from user_tables
where table_name = 'T';


NUM_ROWS NUM_ROWS/2 NUM_ROWS/2/2
-------- ---------- ------------
68076 34038 17019


code5:验证一下上面的说法:
SQL> set autotrace traceonly explain
SQL> select * from t where flag1='N';


Execution Plan
------------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 33479 | 3432K| 292 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 33479 | 3432K| 292 (1)| 00:00:04 |
--------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("FLAG1"='N')


SQL> select * from t where flag2='N';


Execution Plan
----------------------------
Plan hash value: 1601196873


---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 34597 | 3547K| 292 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 34597 | 3547K| 292 (1)| 00:00:04 |
---------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


1 - filter("FLAG2"='N')


--至此一切正常!so far, so good!


code5: here comes the problem
SQL> select * from t where flag1 = 'N' and flag2 = 'N';


Execution Plan
----------------------------
Plan hash value: 1601196873


--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 17014 | 1744K| 292 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T | 17014 | 1744K| 292 (1)| 00:00:04 |
--------------------------------------------------------------------------


Predicate Information (identified by operation id):
----------------------------------------------------


1 - filter("FLAG1" = 'N' AND "FLAG2" = 'N')


--验证了我们前面说的优化器此时异想天开了


code7: 动态采样听令,开始介入
SQL> select /*+ dynamic_samp