菜鸟科技网

runstats命令的具体作用是什么?

runstatsIBM Db2 数据库管理系统中一个至关重要的命令,它的主要作用是为数据库管理器收集和更新表的统计信息,这些统计信息是查询优化器制定高效执行计划的基础。

runstats命令的具体作用是什么?-图1
(图片来源网络,侵删)

可以把它想象成是给数据库的“导航系统”更新实时路况,如果路况信息(统计信息)过时或不准确,导航系统(查询优化器)就可能为你规划出一条拥堵的路线(低效的查询计划)。


runstats 的核心作用

当你对表进行大量数据操作后(如 LOAD, INSERT, UPDATE, DELETE, REORG),表的物理结构和数据分布会发生变化,旧的统计信息就无法准确反映当前表的真实情况。

runstats 命令通过扫描表的数据,收集以下关键信息:

  • 行数: 表中的总行数。
  • 页数: 表占用的数据页和空闲页数量。
  • 键的基数: 对于索引列,有多少个不同的值,高基数意味着列的区分度高(如 ID),低基数意味着区分度低(如 性别)。
  • 数据分布: 数据在列上的分布情况,年龄列的数据是均匀分布还是集中在某个区间?这对于选择索引扫描还是表扫描至关重要。
  • 索引信息: 索引的唯一性、叶子页数、级别等。

为什么这些信息很重要? 查询优化器使用这些统计信息来:

  • 选择访问路径: 决定是使用全表扫描、索引扫描还是其他访问方式。
  • 决定连接策略: 选择嵌套循环连接、哈希连接还是合并连接。
  • 评估成本: 计算不同执行计划的“成本”,并选择成本最低的一个。

runstats 的目标是确保查询优化器拥有做出最佳决策所需的数据,从而生成最高效的查询执行计划,提升数据库性能。


runstats 的基本语法

runstats 命令的语法非常灵活,可以根据需要进行调整。

最简单的语法

RUNSTATS ON TABLE <schema_name>.<table_name>

这个命令会收集表的基本统计信息,但不会收集任何索引的统计信息。

完整的语法示例

RUNSTATS ON TABLE <schema_name>.<table_name>
   [ AND INDEXES ALL | (<index_name1>, <index_name2>, ...) ]
   [ WITH DISTRIBUTION ON COLUMNS (<column_name1>, <column_name2>, ...) ]
   [ WITH DETAILED INDEXES ]
   [ WITH SAMPLE <percentage> PERCENT ]
   [ INCREMENTAL ]
   [ ALLOW WRITE ACCESS ]

主要参数详解

参数 说明 示例
ON TABLE <schema.table> 必需参数,指定要收集统计信息的表。 RUNSTATS ON TABLE HR.EMP
AND INDEXES ALL 强烈推荐,收集该表上所有索引的统计信息,如果不指定,索引信息不会被更新。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL
AND INDEXES (idx1, idx2) 只收集指定列表中的索引的统计信息。 RUNSTATS ON TABLE HR.EMP AND INDEXES (PK_EMP, IDX_DEPT)
WITH DISTRIBUTION ON COLUMNS (col1, col2) 非常强大,收集指定列的数据分布直方图,对于数据倾斜严重的列(如 STATUS 列,大部分是 'ACTIVE',少数是 'INACTIVE'),这个参数能极大优化查询计划。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL WITH DISTRIBUTION ON COLUMNS (STATUS, DEPT_ID)
WITH DETAILED INDEXES 收集更详细的索引统计信息,如索引的碎片程度等,对于索引性能调优很有帮助。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL WITH DETAILED INDEXES
WITH SAMPLE <percentage> PERCENT 对于超大型表,全表扫描收集 runstats 可能非常耗时,可以使用抽样来只扫描一部分数据(如10%),从而快速完成统计信息收集,这是一种性能与准确性之间的权衡。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL WITH SAMPLE 10 PERCENT
INCREMENTAL 增量收集,它不会重置统计信息,而是基于上次的统计信息进行增量更新,这对于频繁变化的表可以显著减少 runstats 的执行时间。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL INCREMENTAL
ALLOW WRITE ACCESS 允许在 runstats 执行期间,其他会话对该表进行 INSERT, UPDATE, DELETE 操作,这可以避免锁表,保证业务的连续性。 RUNSTATS ON TABLE HR.EMP AND INDEXES ALL ALLOW WRITE ACCESS

何时需要运行 runstats

在以下情况后,你应该考虑运行 runstats

  1. 数据加载后: 使用 LOAD 命令向表中导入了大量数据后。
  2. 大量数据操作后: 执行了大量的 INSERT, UPDATE, DELETE 操作,特别是影响了索引列后。
  3. 重组表后: 执行了 REORG 命令后,表的物理结构发生了改变。
  4. 创建新索引后: 新的索引需要被统计信息所覆盖。
  5. 查询性能突然下降: 如果一个原本运行良好的查询突然变慢,可能是由于统计信息过时导致的。
  6. 定期维护: 作为数据库维护计划的一部分,定期(如每周或每月)对关键业务表执行 runstats

实践示例

假设我们有一个 HR 模式下的 EMPLOYEES 表,它有一个主键 PK_EMP 和一个部门索引 IDX_DEPT,我们刚刚用 LOAD 命令导入了最新的员工数据。

推荐的 runstats 命令:

-- 连接到数据库
CONNECT TO MYDB USER db2admin USING password;
-- 执行 RUNSTATS,收集所有索引的统计信息,并收集关键列的分布信息
RUNSTATS ON TABLE HR.EMPLOYEES
   AND INDEXES ALL
   WITH DISTRIBUTION ON COLUMNS (DEPARTMENT_ID, HIRE_DATE, JOB_ID)
   ALLOW WRITE ACCESS;
-- 检查统计信息是否已更新
-- 可以查询 SYSCAT.TABLES 和 SYSCAT.INDEXES 视图中的 CARD 和 STATS_TIME 列
SELECT TABNAME, CARD, LAST_RUNSTATS
FROM SYSCAT.TABLES
WHERE TABNAME = 'EMPLOYEES' AND TABSCHEMA = 'HR';
SELECT INDNAME, CARD, LAST_RUNSTATS
FROM SYSCAT.INDEXES
WHERE TABNAME = 'EMPLOYEES' AND TABSCHEMA = 'HR';
-- 断开连接
CONNECT RESET;

注意事项

  • 性能影响: RUNSTATS 是一个资源密集型操作,因为它需要扫描表数据,在业务高峰期应避免在大型表上执行全量 runstats,优先使用 WITH SAMPLEINCREMENTAL 选项。
  • 锁: 默认情况下,RUNSTATS 会对表获取一个意向锁,可能会阻塞一些操作,使用 ALLOW WRITE ACCESS 可以缓解这个问题。
  • 不是万能药: 如果查询性能问题是由设计缺陷(如缺少索引、不当的SQL)引起的,runstats 无法解决。
  • 版本差异: 不同版本的 Db2 可能在 RUNSTATS 的参数和默认行为上略有差异,请参考对应版本的官方文档。

runstats 是 Db2 DBA 和开发人员必须掌握的核心工具之一,正确、及时地使用 runstats 是保证数据库查询性能的关键。

分享:
扫描分享到社交APP
上一篇
下一篇