对于有列数据非常倾斜的表,做直方图分析很重要,直方图主要讨论的是数据在列上的分布情况。
可以看出,dbms_stats包默认已对id列做了直方图分析。CBO根据直方图信息估算id=99的记录只有1行,这很正确,所以选择索引。
CBO根据直方图信息估算id=1的记录有72483行,几乎和表记录数一致,所以选择了全表扫描。
在这里,仅仅删除直方图的信息,保留表和索引的分析信息
删除直方图后的执行计划
不管谓词id=99还是id=1,CBO估算行数均为725行,而实际id=99的记录只有1条,id=1的记录基本为全部的表记录,所以CBO均使用索引是错的。
在起初,我对T进行分析时,遗漏了estimate_percent=>100这一参数的设置,以至于不管是对谓词id=1还是id=99执行计划均采用全表扫描。我想是因为对id列上的数据分布情况没有分析出来(或者产生了分析信息是错误的),所以应该根据我们的数据量来设置estimate_percent值。
oracle 11gr2 document中对于estimate_percent的解释:
estimate_percent
Percentage of rows to estimate (NULL means compute): The valid range is [0.000001,100]. Use the constant DBMS_STATS.AUTO_SAMPLE_SIZE to have Oracle determine the appropriate sample size for good statistics. This is the default.The default value can be changed using the SET_DATABASE_PREFS Procedure, SET_GLOBAL_PREFS Procedure, SET_SCHEMA_PREFS Procedure and SET_TABLE_PREFS Procedure.
method_opt
Accepts:
FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause]
FOR COLUMNS [size clause] column|attribute [size_clause] [,column|attribute [size_clause]...]
size_clause is defined as size_clause := SIZE {integer | REPEAT | AUTO | SKEWONLY}
- integer : Number of histogram buckets. Must be in the range [1,254].
- REPEAT : Collects histograms only on the columns that already have histograms.
- AUTO : Oracle determines the columns to collect histograms based on data distribution and the workload of the columns.
- SKEWONLY : Oracle determines the columns to collect histograms based on the data distribution of the columns.
The default is FOR ALL COLUMNS SIZE AUTO.The default value can be changed using the SET_PARAM Procedure.
在oracle中要删除直方图信息就是设置bucket的数据为1,可以使用如下两个命令来实现:
analyze table 表 compute statistics for table for columns 列 size 1;
exec dbms_stats.gather_table_stats(ownname => '',tabname=>'',cascade=>true, method_opt=>'for columns 列 size 1');
skewonly 选项的时间性很强,因为它检查每个索引中每列值的分布。如果 dbms_stats 发现一个索引中具有不均匀分布的列,它将为该索引创建直方图,以帮助基于成本的 SQL 优化器决定是使用索引还是全表扫描访问。
begin
dbms_stats. gather_table_stats (
ownname => '',
tabname=>'',
estimate_percent =>dbms_stats.auto_sample_size,
method_opt => 'for columns 列 size skewonly',
cascade=>true,
degree => 2);
end;
cascade
Gather statistics on the indexes for this table. Index statistics gathering is not parallelized. Using this option is equivalent to running the GATHER_INDEX_STATS Procedure on each of the table's indexes. Use the constant DBMS_STATS.AUTO_CASCADE to have Oracle determine whether index statistics to be collected or not. This is the default. The default value can be changed using theSET_PARAM Procedure.
官方文档:http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/stats.htm#PFGRF30103
相关阅读
柱状图(Histogram),绑定变量,bind peeking,cursor_sharing 之间的关系1 柱状图
柱状图(Histogram),绑定变量,bind peeking,cursor_sharing 之间的关系2 绑定变量与柱状图
柱状图(Histogram),绑定变量,bind peeking,cursor_sharing 之间的关系3 柱状图与cursor_sharing