这段时间有客户的10gR2数据库经常遭遇执行计划不稳定的现象,应该是直方图信息(Histogram)+绑定变量窥视(Bind Variable Peeking)造成的问题,藉此分享一下直方图的使用经验,但是我非常希望能听到针对本文的不同声音。测试环境Oracle 11.2.0.1 for Windows X64。
创建一个测试表。
DROP TABLE t; CREATE TABLE t AS SELECT rownum n1, ROUND(rownum/100) n2, ‘xxxx’ n3 FROM dba_objects WHERE rownum<=10000;
这样我们生成了一张表T,其中有一万行记录。 N1字段可以认为是主键,有10000个distinct值(1-10000),这是一个数据分布均匀的字段; N2字段有101个distinct值,除了第一个值0和最后一个值101之外,其它的值都有100行记录,我们可以认为这是一个数据分布均匀的字段; N3字段有10000个值都是xxxx,实际上这也仍然是一个分布均匀的字段。
对于这三种类型的字段,我们都不应该去收集直方图信息,因为没有意义。那么直方图信息之所以需要存在的根本意义在哪里?
一. 我们何时该做 直方图究其根本实际上就是一个数据分布的图示,这个图示是为了在生成SQL执行计划的时候给Oracle的CBO更多的信息,换句话说,就是当在where条件中的某些列可能由于列值的不同而希望CBO制定出不同的执行计划时,我们需要直方图。
反过来说,什么情况下我们不需要直方图呢?或者说直方图的存在是没有意义的呢? 1. 当此列不用于查询时,也就是这个字段永远不会出现在where条件中(注意:即使是用于表连接那也算是出现在where条件中)。 2. 当此列无论给予什么比较值,我们都希望永远是一种执行计划时。上面例子中的3个字段都属于这种情况。 对于N1或者N2出现在where条件中,我们希望永远是用该列上的索引扫描(当然需要在该列上先创建索引),对于N3出现在where条件中,我们希望永远是全表扫描。这样的执行计划的制定,只要有表级别的统计信息就足够了,直方图信息的出现不但不会对制定正确的执行计划有帮助,甚至会出现奇怪的现象导致执行计划不稳定。
二. 我们可以怎样做 那么我们继续看一下收集直方图信息的方法,众所周知,是需要使用DBMS_STATS.GATHER_TABLE_STATS存储过程的,并且是由这个存储过程中的method_opt参数决定的。可以由以下几种选择。
method_opt=>’for columns size skewonly [column_name]‘ 什么是SKEWONLY?先看一下Oracle官方文档中的定义。
Oracle determines the columns to . . . → Read More: Oracle Histogram Investigation