直方图当某列数据分布不均衡,为了让CBO能生成最佳的执行计划,我们可能需要对表收集直方图,直方图最大的桶数(Bucket)是254。收集直方图是一个很耗时的过程,如无必要,千万别去收集直方图。
请注意在 OLTP 系统中
如果没有必要
千万不要去收集直方图统计
因为你收集了直方图
可能遇到绑定变量窥探
9i,10g里面几乎没有好办法解决
11g里出了一个自适应游标解决了这个但也有风险
之所以有绑定变量窥探
就是因为收集了直方图
我们来举个例子探究下直方图到底是干什么的
create table test as select * from dba_objects;
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT',
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns sizeskewonly',
no_invalidate => FALSE,
degree => 1,
cascade => TRUE);
END;
/
select a.column_name,
b.num_rows,
a.num_distinct Cardinality,
round(a.num_distinct /b.num_rows * 100, 2) selectivity,
a.histogram,
a.num_buckets
from dba_tab_col_statistics a, dba_tables b
where a.owner = b.owner
and a.table_name = b.table_name
and a.owner = 'SCOTT'
and a.table_name = 'TEST';
为了讲解直方图,我收集统计信息的时候是method_opt => 'for all columns size skewonly',
正式的生产环境中,最好别用allcolumns方式收集直方图,因为allcolumns几乎会对所有列都收集直方图信息,但是有些列并不会出现在where条件中,我们去收集并不会出现在where条件中的列就浪费了资源,并且OLTP环境中,能不收集直方图就不要收集直方图。
Oracle的直方图有两种:
一种是频率直方图(FREQUENCYHISTOGRAM),当列中Distinct_keys较少(小于254),如果不手工指定直方图桶数(BUCKET),Oracle就会自动的创建频率直方图,并且桶数(BUCKET)等于Distinct_Keys。
owner这列基数等于多少?发现这个规律没?
当一个列的基数