1

在查看我的表 (m_CURRENT) 的 dba_tab_col_statistics 时,我注意到 TNE 列的 num_buckets 值在一个数据库上为 75,在另一个数据库上为 254。DB是Oracle 10g。

这似乎是两个表之间的主要区别。有没有办法让两个数据库都匹配 num_bucket 值?

我有一个删除语句,在一个数据库上速度很快,而在另一个数据库上速度很慢。我知道查询计划在两个数据库上可能不同的原因有很多。经过大量分析,我怀疑让慢速查询数据库具有相同的 num_bucket 设置可以确保我的删除语句在索引 TNE_idx 上执行 range_scan(快速)而不是 fast_full_scan(在这种情况下慢)。

4

2 回答 2

1

I want to follow up, DazzaL's answer was very informative, but I was wrong, the buckets did not make a difference. I could have saved a lot of time by running
explain plan for delete blah blah blah

then

select * from table(dbms_xplan.display) and focusing on the right step id.

I zeroed in on step id 5 where a index fast full scan was being used when I should have started on step 2 where the two database plans were different. I saw the fast database doing nested loop anti join and the slow database doing a merge join anti. Once I added the (undocumented?) hint NL_AJ with no parameters in the subquery, the desired fast index_range_scan was used.

As I write this I wonder if the bucket number matching was important, but I don't have the time to retest. It ain't broke, so I will not touch it!

于 2012-12-21T15:22:35.830 回答
1

你如何收集两个数据库的统计数据,你有一个常规的统计数据收集脚本吗?您可以一次性完成此操作以仅在该列上收集直方图:

begin
dbms_stats.gather_table_stats(user,'M_CURRENT', 
          method_opt=>'for columns TNE size 254', cascade=>false, 
           granularity=>'ALL', degree=>8);
end;
/

size 参数将设置存储桶(如果不同值的数量少于该数量,则结果将更少)。

上面没有指定estimate_pct,因此将采样一个较小的值群体而不是100%。如果您想要 100%,则在 estimate_pct 参数中指定*),但如果您有常规脚本,则稍后可能会被覆盖。

* 您可以通过比较 dba_tab_col_statistics 上的 sample_size 与 dba_tables 上的 num_rows 来检查当前样本大小

于 2012-12-20T14:54:34.677 回答