oracle 如何正确收集统计信息

本篇主要是从两个角度出发:
1、什么统计信息;
2、怎么正确收集统计信息(dbms_stats)

一、统计信息相关概念

1、什么是统计信息?
oracle数据库中的统计信息存储在数据字典中,从多个维度描述了oracle数据库里的详细信息。

2、统计信息作用是什么?
oracle CBO优化器会利用统计信息计算目标SQL各种可能、不同的执行路径的成本,并从中选择一条最小的执行路径来作为目标SQL的执行计划。(统计信息不准确,SQL的执行计划会走错,SQL会出现性能问题)

3、统计信息分类:

  • 表的统计信息
    表的统计信息主要包含表的总行数(num_rows),表块数(blocks)以及平均长度(avg_row_len)
  • 索引的统计信息
    索引的统计信息描述了索引的详细信息,所以索引的层级、叶子块的数量、聚簇因子等
  • 列统计信息
    列统计信息记录了列的distinct值的数量、null的数量、列最小值和列最大值。
  • 系统统计信息
    系统统计信息是描述了oracle数据库服务器的系统处理能力,包含cpu和I/O两个方面,可以通过这两个方面来知道数据库服务器的实际处理能力
  • 数据字典统计信息
    描述了字典基表(tab , i n d ,ind ,ind等),数据字典基表上的索引。
  • 内部对象统计信息
    记录了一些内部表(x 系 统 表 ) 的 详 细 信 息 , 它 的 维 度 和 普 通 表 的 统 计 信 息 类 似 , 但 是 其 表 块 数 为 0 , x 系统表)的详细信息,它的维度和普通表的统计信息类似,但是其表块数为0,x 0x实际上只是oracle自定义的内存结构,不占用实际物理空间。

二、收集统计信息方法选择

oracle有两种方法收集统计信息,1、analyze;2、dbms_stats

2.1 analyze命令收集

oracle 7开始,通过analyze命令来收集表、索引、列的统计信息。以下是一些典型的用法。

  • 采样比为15%,对test表搜集统计信息
analyze table test estimate statistics smaple 15 percent for table;
  • 计算模式 对test表收集统计信息
analyze table test compute statistics for table;

该模式下,只有test表有统计信息,test的列和索引都没有统计信息,且收集的统计信息和实际情况是一致的。

  • 计算模式下对test表 列1和列2收集统计信息
analyze table test compute statistics for cloumns 列1,列2;

只会对列1和列2收集统计信息,且之前的覆盖掉之前的收集统计信息。

  • 计算模式下同时对表和列1和列2收集统计信息
analyze table test compute statistics for table for cloumns 列1,列2;
  • 收集索引统计信息
analyze index idx_1 statistics;
  • 删除统计信息
analyze table test delete statistics;

删除test表、列、所有索引的统计信息

analyze index idx_1 delete statistics;

2.2 dbms_stats包收集统计信息

oracle 8.1.5开始,dbms_stats被广泛应用于统计信息收集,也是oracle官方推荐的方式。
dbms_stats有4个存储过程。

  • gather_table_stats:用于收集目标表、列和索引的统计信息。
    示例:
    收集test表的统计信息
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 15, --采样比是15%
                                method_opt       => 'for table',
                                cascade          => false);  --默认是true,级联收集
END;
/

  • gather_index_stats:用于收集指定统计信息。
    示例:收集索引idx_text的统计信息
BEGIN
  DBMS_STATS.GATHER_INDEX_STATS(ownname          => 'SCOTT',
                                indname          => 'IDX_TEST',
                                estimate_percent => 100,
								);
END;
/
  • gather_schema_stats:用于收集指定schema下的所有对象统计信息。
    示例:收集scott用户下的所有对象
BEGIN
  DBMS_STATS.GATHER_SCHEMA_STATS(ownname		 => 'SCOTT',
                                cascade			 =>true,
                                granularity=>'ALL', --收集分区表
								);
END;
/
  • gather_database_stats:用于书籍全库所有的统计信息。
    示例:收集全库的统计信息
BEGIN
  DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent=>100,
                                   degree=>8,
                                   cascade=>true,
                                   granularity=>'ALL', --收集分区表
								);
END;
/

2.2.1 DBMS_STATS重要参数详解

ownname:表示表的拥有者,不区分大小写。

tabname:表示表名字,不区分大小写。

granularity:表示收集统计信息的粒度,该选项只对分区表生效,默认为 AUTO,表示让Oracle根据表的分区类型自己判断如何收集分区表的统计信息。
对于该选项,我们一般采用AUTO 方式,也就是数据库默认方式,因此在后面的脚本中,省略该选项。

estimate_percent“”表示采样率,范围是0.000 001~100。
这个参数主要是用于CBO估算表的总行数,采样率越高,CBO估算的表行数越接近于真实值,执行计划越能走正确。
估算总行数=样本大小(DBA_TAB_STATISTICS.SAMPLE_SIZE)*100/采样率(estimate_percent)
这个参数可能对于很多新手来说都不知道怎么设置:
一般对小于 1GB 的表进行100%采样,因为表很小,即使100%采样速度也比较快。有时候小表有可能数据分布不均衡,如果没有100%采样,可能会导致统计信息不准。
因此建议对小表 100%采样。我们一般对表大小在1GB~5GB 的表采样50%,对大于5GB的表采样30%。如果表特别大,有几十甚至上百 GB,我们建议应该先对表进行分区,然后分别对每个分区收集统计信息。一般情况下,为了确保统计信息比较准确,我们建议采样率不要低于30%。
<1GB 建议采样比100%
1GB~5GB 建议采样比50%
>5GB 建议采样比30%

method_opt:用于控制收集直方图策略。
直方图简单来说就是数据库了解表中某列的数据分布,从而更正确的走更优的执行计划
method_opt => ‘for all columns size 1’ 表示所有列都不收集直方图
method_opt => ‘for all columns size skewonly’ 表示对表中所有列收集自动判断是否收集直方图。选择率非常高的列和null的列不会收集(谨慎使用)
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,收集统计信息的时候就按照表的 degree 来开并行。可以查询 DBA_TABLES.degree 来查看表的 degree,一般情况下,表的 degree 都为 1。我们建议可以根据当时系统的负载、系统中 CPU 的个数以及表大小来综合判断设置并行度。

cascade :表示在收集表的统计信息的时候,是否级联收集索引的统计信息,默认值为DBMS_STATS.AUTO_CASCADE,表示让 Oracle 自己判断是否级联收集索引的统计信息。

2.3 analyze和dbms_stats的区别

  1. analyze命令不能正确的手机分区表的统计信息,而dbms_stats包却可以。
  2. analyze命令不能并行收集统计信息,而dbms_stats包可以。
  3. analyze命令不能收集x$的统计信息

所以选择推荐使用dbms_stats来对表进行统计信息收集。

2.4 推荐建议收集统计信息脚本

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size repeat',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                granularity      => 'ALL',
                                cascade          => TRUE);
END;
/

唯一需要注意选择的地方是:
estimate_percent :
<1GB 建议采样比100%
1GB~5GB 建议采样比50%
>5GB 建议采样比30%
(朋友们可以自己尝试用存储过程去判断表大小,自定义收集统计信息脚本)
degree :
根据服务器的资源,和业务负载来指定
method_opt :
系统刚上线使用auto,业务系统稳定后使用repeat。

Oracle 是一种常用的关系型数据库管理系统,性能优化是确保数据库系统能够高效运行的关键方面之一。以下是一些常见的 Oracle 性能优化技术: 1. 索引优化:通过创建适当的索引,可以加快查询速度。定期检查索引的使用情况,并根据查询需求调整索引策略。 2. SQL 优化:分析和优化 SQL 查询语句,包括使用正确的查询语法、减少不必要的联接和子查询、避免全扫描等。使用 SQL 性能分析工具来帮助识别潜在的性能问题。 3. 内存管理:适当配置数据库的内存参数,如 SGA(System Global Area)和 PGA(Program Global Area),可以提高性能。合理分配内存资源,避免过度使用或浪费内存。 4. I/O 优化:确保磁盘子系统能够满足数据库的读写需求。使用合理的文件布局和存储策略,优化空间和数据文件的分布。配置适当的缓存和写入策略,减少磁盘 I/O 操作。 5. 统计信息收集:及时收集和更新和索引的统计信息,以便优化查询计划。使用统计信息收集工具,如 Oracle收集统计信息任务(GATHER_STATS_JOB),自动维护统计信息。 6. 并发控制:合理设置并发控制参数,如连接数、锁等待时间等,以平衡并发访问和系统响应时间。使用合适的并发控制机制,如乐观并发控制或悲观并发控制,避免死锁和冲突。 7. 数据库设计优化:良好的数据库设计可以提升性能。合理规划结构、关系和约束,避免数据冗余和不一致。使用分区、分、视图等技术,优化数据存储和查询效率。 以上是一些常见的 Oracle 性能优化技术,根据具体情况可以进行适当调整和组合使用。还可以使用 Oracle 提供的性能监控和诊断工具,如 AWR(Automatic Workload Repository)报告和 SQL Trace,来帮助定位和解决性能问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值