在Oracle数据库,执行sql语句的时候,会根据统计信息选择最优执行计划,当执行性能比自己想象的慢时,就有可能是统计信息不是最新导致。
表的统计信息主要包含表的总行数(num_rows)、表的块数(blocks)以及行平均长度(avg_row_len)。
通过查询数据字典DBA_TABLES 查看表的统计信息
通过查询数据字典DBA_TAB_COL_STATISTICS查看表的常用列的统计信息。第一个列表示列名字,第二个列表示列的基数,第三个列表示列中NULL值的数量,第四个列表示直方图的桶数,最后一个列表示直方图类型。
查看表和列的统计信息
当统计信息中的NUM_ROWS与表中实际的行数不一致的时候,说明统计信息不是最新的。
这时候我们应当适时收集表的统计信息。
以下是统计信息的参数说明:
ownname 表示表的拥有者,不区分大小写。
estimate_percent 表示采样率,范围是0.000 001~100。
优化器在计算执行计划的成本时依赖于统计信息,如果没有收集统计信息,或者是统计信息过期了,那么优化器就会出现严重偏差,从而导致性能问题。因此要确保统计信息准确性。虽然数据库自带有JOB 每天晚上会定时收集数据库中所有表的统计信息,但是如果数据库特别大,自带的JOB 无法完成全库统计信息收集。一些资深的DBA 会关闭数据库自带的统计信息收集JOB,根据实际情况自己定制收集统计信息策略。
采样率,建议根据表的段大小,小于1g是100;大于等于1g,小于等于5g是50;大于5g是30。
method_opt 用于控制收集直方图策略。
method_opt => 'for all columns size 1' 表示所有列都不收集直方图
method_opt => 'for all columns size skewonly' 表示对表中所有列收集自动判断是否收集直方图
method_opt => 'for columns object_type size skewonly' 表示单独对OBJECT_TYPE 列收集直方图,对于其余列,如果之前收集过直方图,现在也收集直方图。
method_opt => 'for all columns size auto' 表示对出现在where 条件中的列自动判断是否收集直方图。
method_opt => 'for all columns size repeat' 表示当前有哪些列收集了直方图,现在就对哪些列收集直方图。对一个运行稳定的系统,我们应该采用REPEAT 方式收集直方图。
no_invalidate 表示共享池中涉及到该表的游标是否立即失效,默认值为DBMS_STATS.
auto_invalidate,表示让Oracle 自己决定是否立即失效。我们建议将no_invalidate 参数设置为FALSE,立即失效。因为我们发现有时候SQL 执行缓慢是因为统计信息过期导致,重新收集了统计信息之后执行计划还是没有更改,原因就在于没有将这个参数设置为false。
degree 表示收集统计信息的并行度,默认为NULL。如果表没有设置degree,收集统计信息的时候后就不开并行; 如果表设置了degree,收集统计信息的时候就按照表的degree 来开并行。 可以查询DBA_TABLES.degree 来查看表的degree,一般情况下,表的degree 都为1。 我们建议可以根据当时系统的负载、系统中CPU 的个数以及表大小来综合判断设置并行度。
cascade 表示在收集表的统计信息的时候,是否级联收集索引的统计信息,默认值为DBMS_STATS.AUTO_CASCADE,表示让Oracle 自己判断是否级联收集索引的统计信息。
我们一般将其设置为TRUE,在收集表的统计信息的时候,级联收集索引的统计信息。