基数与现实相去甚远

rfu*_*sca 7 oracle oracle-11g-r2

我有一张表,其中计划的基数似乎太高了——尽管更新了统计数据,甚至尝试了 Oracle 11gR2 的动态采样。

select count(*) 
from table1 
where col1 = 123 
and col2 = '1';
Run Code Online (Sandbox Code Playgroud)

col1 的一个值的估计基数大约为 29k,当它返回的实际行数为 637 时。对于另一个值,当实际行数为 67k 时,它的计划基数为 460k。一般来说,这会导致它选择非常糟糕的计划。

我试过更新统计信息:

exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1');
Run Code Online (Sandbox Code Playgroud)

或者

exec DBMS_STATS.gather_table_stats (ownname => 'ME', tabname =>'table1',estimate_percent =>100);
Run Code Online (Sandbox Code Playgroud)

我已经尝试了 dynamic_samping (1-10) 的各种值,但没有任何改变它显着:

select /*+ dynamic_sampling(t1 10) */ count(*) 
from table1 t1 
where col1 = 123 
and col2 = '1';
Run Code Online (Sandbox Code Playgroud)

dyanmic_sampling 会改变,但它仍然关闭近 50-100 倍。

我怎样才能得到更好的估计?

Jac*_*las 9

我要做的第一件事是使用这些查询分别检查列的统计信息:

  • select count(*) from table1 where col1 = 123;
  • select count(*) from table1 where col2 = '1';

如果此处估计的基数与实际行数更吻合,则意味着 CBO 无法根据 vanilla 生成的直方图猜测的列之间存在某种相关性gather_table_stats动态采样 应该以增加解析时间为代价来改善事情,但不是灵丹妙药。

或者,使用 11g,“ Oracle 数据库还可以收集表中一组列的统计信息

  1. 创建列组
  2. 收集列组的统计信息