1.将整个schema的表开启morning ,使用alter_schema_tab_monitoring来做时
DBMS_STATS.alter_schema_tab_monitoring('SCHEMA_NAME',TRUE);
2. options 选项:
GATHER EMPTY 收集没有统计信息的表分析信息
GATHER 收集所有的统计信息
GATHER STALE 仅重新分析那些发生了10%变化的表, 根据dba_tab_modifications视图来跟踪发生变动的表,跟据表的插入、更新和删除量决定是否进行更新统计信息,需发对表开启morning。
GATHER AUTO 分析当前没有统计的对象,以及统计数据过期的对象,同样根据dba_tab_modifications视图,需发对表开启morning
3. method_opt选项
dbms_stats的method_opt参数尤其适合在表和索引数据发生变化时刷新统计数据。method_opt参数也适合用于判断哪些列需要直方图(histograms)。
某些情况下,索引内的各个值的分布会影响CBO是使用一个索引还是执行一次全表扫描的决策。例如,假如在where子句中指定的值的数量不对称,全表扫描就显得比索引访问更经济。
如果你有一个高度倾斜的索引(某些值的行数不对称),就可创建Oracle直方图统计。但在现实世界中,出现这种情况的机率相当小。使用CBO时,最常见的错误之一就是在CBO统计中不必要地引入直方图。根据经验,只有在列值要求必须修改执行计划时,才应使用直方图。
为了智能地生成直方图,Oracle为dbms_stats准备了method_opt参数。在method_opt子句中,还有一些重要的新选项,包括skewonly,repeat和auto:method_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat'
method_opt=>'for all columns size auto'
skewonly选项会耗费大量处理时间,因为它要检查每个索引中的每个列的值的分布情况,发现索引为倾斜分布时,将为这个索引收集histograms,让CBO可以判断是采用index,还是直接full table scan。
重新分析统计数据时,使用repeat选项,重新分析任务所消耗的资源就会少一些。使用repeat选项(清单C)时,只会为现有的直方图重新分析索引,不再搜索其他直方图机会。定期重新分析统计数据时,你应该采取这种方式
4. no_invalidate 分析完成后,只对后面重新分析的语句有效,对当前已经在执行的语句无效。
5.统计信息收集策略
以下为摘自Donald K. Burleson 原文路径:http://otn.oracle.com/oramag/webcolumns/2003/techarticles/burleson_cbo_pt1.html
成功使用CBO的关键是稳定性,下面是一些成功使用CBO的基本事项。
●只在必需的时候才进行统计数据的重新分析
Oracle DBA们最容易犯的一个普遍错误就是经常性的对系统的统计数据进行重新分析。记住:做这件事的唯一目的是改变SQL语句的执行计划,如果这个执行计划没有被破坏,就不要去修复它。如果你对SQL语句的性能还满意的话,重新分析产生统计数据以后可能会产生较大的性能问题,并给开发团队带来影响。实际运用中,也是极少数的Oracle系统才会周期性的对统计数据进行重新分析。
一般来讲,一个数据库应用系统的基本架构是不会轻易改变,大数据量的表仍然是很大,索引列的分布、基数值等等也很少变化。只有下列几种情况的数据库才可能经常对整个系统的统计数据重新分析:
1、用于数据分析的数据库
有一些由于科学试验数据分析的数据库系统,经常会更换整个一套的试验数据,那么这种情况下当数据库重新load了一套数据以后,可以立即重新对统计数据进行分析。
2、高度变化的数据库
这是极少数的例子,表的大小或者索引列的数据在剧烈的变化,比如一张表有100条记录,一周以后就变成10000条记录。这种情况下也可以考虑周期性的进行统计数据分析。
●强迫开发人员调整自己的SQL
很多开发人员错误的认为,他们的任务就是编写SQL语句然后从数据库中获得正确的数据。但是实际上编写出SQL语句只是开发人员一半的工作,在一个成功的Oracle应用系统中,会要求开发人员的SQL语句采用最优化的方式访问数据库,并且保证SQL语句的执行计划在新的SQL之间的可移植性。
令人惊讶的是,在许多Oracle应用系统中都不怎么考虑具体SQL语句的执行计划,认为CBO是很智能的,无论如何都可以为我们提供最好的SQL语句执行计划。
同一个查询在SQL语句中可能有不垃圾广告式的写法,而每一种写法都可能有不同的执行计划。观察下面的例子,每一个查询的结果都是一样的,但是执行计划却相去甚远。
-- 使用了不正确的子查询
select
book_title
from
book
where
book_key not in (select book_key from sales);
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=1 Bytes=64)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=1 Bytes=64)
3 1 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=5 Bytes=25)
-- 使用了两张表的外连接
select
book_title
from
book b,
sales s
where
b.book_key = s.book_key(+)
and
quantity is null;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=3 Card=100 Bytes=8200)
1 0 FILTER
2 1 FILTER
3 2 HASH JOIN (OUTER)
4 3 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=20 Bytes=1280)
5 3 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=100 Bytes=1800)
-- 使用了三个正确的子查询
select
book_title
from
book
where
book_title not in (
select
distinct
book_title
from
book,
sales
where
book.book_key = sales.book_key
and
quantity > 0);
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=1 Bytes=59)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=1 Bytes=59)
3 1 FILTER
4 3 NESTED LOOPS (Cost=6 Card=1 Bytes=82)
5 4 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=5 Bytes=90)
6 4 TABLE ACCESS (BY INDEX ROWID) OF 'BOOK' (Cost=1 Card=1)
7 6 INDEX (UNIQUE SCAN) OF 'PK_BOOK' (UNIQUE)
我们看到,正确的SQL语句写法产生的执行计划是如此的不同。明智的开发人员知道如何去编写能够产生最好执行计划的SQL语句,明智的Oracle应用系统也会主动训练开发人员去编写最有效的SQL语句。
下面是一些帮助开发人员优化SQL语句的技巧:
1、 使用 autotrace 和 TKPROF 功能去分析SQL语句的执行计划;
2、 保证所有生产环境中的SQL语句都是在测试环境中经过优化的;
3、 制定一个性能优化的标准,而不是只要求开发人员编写出最快的SQL语句。根据这种标准,好的开发人员应该能够写出最有效的SQL语句。
●谨慎管理CBO统计数据
成功的Oracle系统会谨慎管理他们的CBO统计数据,以保证CBO在测试环境和生产环境中以同样的方式工作。一个聪明的DBA会在得到高质量的CBO统计数据以后,把这些统计数据移植到测试环境中,这样SQL语句的执行计划在测试环境和生产环境中就是一样的了。
对DBA来说,一个重要的工作就是收集和发布CBO统计数据,并随时保持一套当前运行环境的最精确的统计数据。在一些情况下,可能会有不止一套的优化统计数据。比如,对OLTP运行的最好的统计数据可能对数据仓库运行却不是最好的,在这种情况下,DBA就需要保持两套统计数据,并根据不同的运行条件导入系统。
可以使用 dbms_stats 包中的 export_system_stats 存储过程来完成CBO统计数据的导出。下面的例子中,我们把当前CBO统计数据导出到一张名叫 stats_table_oltp的表中。
dbms_stats.export_system_stats(‘stats_table_oltp’)
导出以后,我们就可以把这张表拷贝到别的实例中,当系统的运行模式改变以后,使用 dbms_stats 包中的 import_system_stats 存储过程来完成CBO统计数据的导入。
dbms_stats.import_system_stats(‘stats_table_oltp’)
●千万不要随便改动CBO参数的值
改动CBO相关参数的值是非常危险的,因为一个小小的改动可能就会对整个系统的执行性能带来极大的负面影响,只有在经过严格的系统测试以后才能改动这些参数的值。可能带来极大影响的参数值包括:optimizer_mode, optimizer_index_cost_adj, and optimizer_index_caching。而其他参数,比如 hash_area_size , sort_area_size, 参数值的改变就不是那么危险了,可以在会话级进行改变以帮助CBO优化查询。
●保证静态的执行计划
成功的CBO应用会通过谨慎管理统计数据来锁定SQL执行计划,同时保证存储的优化计划的稳定性,或者在具体的SQL语句中加入一些细节上的提示。
记住:重新分析一个系统的统计数据,可能会导致成千上万的SQL语句改变其执行计划。许多Oracle应用系统要求所有的SQL语句在测试环境中经过验证,保证在功能上和生产环境是一致的。
2.4.4 CBO的思考
尽管我们已经对CBO的不少细节有了了解,但是由于随着Oracle新版本的不断推出,CBO变得越来越强大,同时也越来越复杂,我们仍然有许多关于CBO的知识需要学习。
下面是一些关于CBO调整的提纲性的建议,供准备进行CBO调整的DBA们思考。
●DBA可以提供一些Oracle参数的配置对CBO进行控制,但是只能在有限的环境下谨慎的改变这些参数;
●CBO依靠统计数据来产生SQL语句的优化的执行计划,可以通过 dbms_stats 包来分析、产生统计数据;
●DBA们的一项重要任务就是收集、管理CBO统计数据,这些数据可以被收集、存储,也可以在相关的实例中进行移植,以保证执行计划的连贯性。
●在没有使用 export_system_stats 存储过程导出原来的统计数据以前,重新对系统的统计数据进行分析是十分危险的,因为成千上万的SQL语句的执行计划将可能全部改变,而你却不能恢复原来的SQL性能。只有在系统的数据发生巨大变化时,才可能需要对整个系统的统计数据进行重新分析。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10834762/viewspace-410046/ ,如需转载,请注明出处,否则将追究法律责任。