当Where子句引用了列值分布存在明显偏差的列时:当这种偏差相当明显时,以至于 WHERE 子句中的值将会使优化器选择不同的执行计划。这时应该使用直方图来帮助优化器来修正执行路径。(注意:如果查询不引用该列,则创建直方图没有意义。这种错误很常见,许多 DBA 会在偏差列上创建柱状图,即使没有任何查询引用该列。)
The preceding query will create a ten-bucket histogram on the COMPANY table, as shown in Figure 2-2. The values for the COMPANY_CODE column will be divided into the ten buckets as displayed in the figure. This example shows a large number (80 percent) of the company_code is equal to 1430. As is also shown in the figure, most of the width-balanced buckets contain only 3 rows; a single bucket contains 73 rows. In the height-balanced version of this distribution, each bucket has the same number of rows and most of the bucket endpoints are '1430', reflecting the skewed distribution of the data.
5.实验
5.1.1创建实验表
1 2 3 4 5 6 7 8 9 10 11
SQL>createtableobj asselect* from dba_objects; SQL>createindexobj_id_idx on obj(object_id)onlinenologging; SQL>SELECTMAX(object_id),MIN(object_id)FROMobj; MAX(OBJECT_ID) MIN(OBJECT_ID) ————– ————– 58410 2 –制造不均匀数据分布 SQL> UPDATE obj SET object_id =1000 WHERE object_id >100ANDobject_id <54000; SQL>commit;
5.1.2创建直方图
1 2 3 4 5 6 7 8 9
BEGIN DBMS_STATS.gather_table_stats(cascade =>TRUE, degree =>2, estimate_percent =>100, force =>TRUE, ownname =>'FUNG', tabname =>'OBJ'); END; /
在gather_table_stats方法中,默认的method_opt值为:FOR ALL COLUMNS SIZE AUTO,所以也是会收集直方图的统计信息(和oracle版本相关),其中degree 指定了并行度视主机的CPU 个数而定,estimate_percent 指定了采样比率,
auto 目的是让oracle 来决定采样收集的比率,绘制直方图时会根据采样的数据分析结果来绘制,当然也可以人为指定采样比率。如: estimate_percent=>20 指定采样比率为20%,cascade=>true 指定收集相关表的索引的统计信息,该参数默认为false,因此
使用dbms_stats 收集统计信息时默认是不收集表的索引信息的。
–注意:ENDPOINT_NUMBER ,ENDPOINT_VALUE 的分布情况
1 2 3
SQL>SELECT * FROM user_histograms WHERE table_name ='OBJ'ANDcolumn_name ='OBJECT_ID';
1 2 3 4
SQL>SELECTCOLUMN_NAME,HISTOGRAM FROMUSER_TAB_COLS WHERE TABLE_NAME='OBJ' AND column_name='OBJECT_ID'; COLUMN_NAME HISTOGRAM ——————– —————————— OBJECT_ID HEIGHT BALANCED
5.1.3直方图执行计划
SQL>selectobject_name from obj whereobject_id=100;
CBO选择index range scan。
SQL>selectobject_name from obj whereobject_id=1000;