我有一张表,其中计划的基数似乎太高了——尽管更新了统计数据,甚至尝试对 Oracle 11gR2 进行动态采样。
select count(*)
from table1
where col1 = 123
and col2 = '1';
当它返回的实际行数为 637 时,col1 的一个值的估计基数约为 29k。对于另一个值,当实际行数为 67k 时,其计划基数为 460k。总的来说,这导致它选择了非常糟糕的计划。
我试过更新统计数据:
exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1');
或者
exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1',estimate_percent =>100);
我已经尝试了 dynamic_samping (1-10) 的各种值,但没有任何显着改变:
select /*+ dynamic_sampling(t1 10) */ count(*)
from table1 t1
where col1 = 123
and col2 = '1';
dyanmic_sampling 会改变,但仍然会降低近 50-100 倍。
我怎样才能得到更好的估计?
我要做的第一件事是使用这些查询分别检查列的统计信息:
select count(*) from table1 where col1 = 123;
select count(*) from table1 where col2 = '1';
如果此处估计的基数与实际行数吻合得更好,则意味着 CBO 无法根据 vanilla 生成的直方图猜测列之间存在某种相关性
gather_table_stats
。动态采样 应该以增加解析时间为代价来改善事情,但这不是灵丹妙药。或者,对于 11g,“ Oracle 数据库还可以收集表中一组列的统计信息”