首页 » 技术分享 » DB2 优化 RUNSTATS:排除索引碎片故障

DB2 优化 RUNSTATS:排除索引碎片故障

 

简介

索引碎片可能由正常的数据库活动导致,比如 INSERT 和 UPDATE。当索引变得高度碎片化时,会对 RUNSTATS 性能产生重大影响。您可学习识别何时出现了这种情形,并采取更正措施。

本文适用于运行 DB2 9.7 或更低版本的安装。在引入了提前读预取 (readahead prefetching) 的 DB2 10.1 中,索引碎片对 RUNSTATS 性能不会产生同样的影响。

索引扫描性能对 RUNSTATS 性能有何影响

在您提交以下命令时,DB2 会收集表和它的所有索引的统计数据:

RUNSTATS ON TABLE MY.TABLE1 AND INDEXES ALL

它首先扫描表来确定表统计数据,然后扫描表的所有索引,一次一个,以确定索引统计数据。

对于具有多个索引的大型表,索引扫描性能是 RUNSTATS 性能的一个重要影响因素。如果在扫描用户请求页面之前,将合适的索引页面预取到缓冲池中,索引扫描的运行速度将会很快。但是,如果扫描用户必须等待磁盘 I/O 将页面加载到缓冲池中,索引扫描的运行速度就会欠佳。其他数据库操作(比如查询)也将使用索引扫描。但是,RUNSTATS 会全面扫描表的所有索引,一次扫描一个,而查询可能仅扫描表的某个索引的一部分。当索引扫描性能很糟糕时,可在 RUNSTATS 中很明显地感觉到。

DB2 9.7 和更低的版本使用顺序检测来确定是否应该执行索引预取。在 RUNSTATS 按照索引的键的顺序处理索引页面时,如果数据库管理器检测到对索引页面的顺序访问,就会启动预取。当一个索引未碎片化并具有物理上连续的页面时,预取很有用。但是,如果索引的页面分散在整个表空间中,如果预取的大多数页面都不会被使用,那么预取页面可能很浪费资源。

索引碎片是由多种因素引起的。一个因素是一个表有多个索引。一个表的索引存储在单个索引对象中(分区表的未分区索引除外),因此一个索引的页面可与另一个索引的页面相混合。另一个因素是 INSERT 和 UPDATE 活动可能引起的索引页面拆分。

索引重组可将索引数据重新构建到未碎片化的物理上连续的页面中。这使顺序检测能够将页面预取到缓冲池中,以便 RUNSTATS 有需要时下一页已经可以使用。结果将会得到更快的 RUNSTATS 运行速度。

DB2 10.1 提供了新的预取功能,其中索引碎片不再对索引扫描性能具有重大的有害影响。这将在本文后面更详细地讨论。

一个包含碎片化的索引和未碎片化的索引的示例

为了演示碎片化的索引对 RUNSTATS 性能的影响,让我们创建索引碎片化的一种极端情形。清单 1 包含用来创建一个包含 1000 万行的表的命令。它首先创建 5 个索引,然后插入数据。使用这个 insert 方法,不同索引的页面将混合在一起,而且每个索引被严重碎片化。

清单 1. 创建碎片化的索引的脚本
-- run this CLP file with autocommit off (db2 +c -tvf FILE)

connect to db97;

-- create not logged initially table
drop table demo.t1;
CREATE TABLE demo.t1 (i1 int not null,
                      i2 int not null,
                      i3 int not null,
                      i4 int not null,
                      i5 int not null,
                      i6 int not null,
                      i7 int not null)
       not logged initially;

-- create indexes BEFORE inserting data 
create index demo.t1i1    on demo.t1 (i1);
create index demo.t1i2    on demo.t1 (i2);
create index demo.t1i3    on demo.t1 (i3);
create index demo.t1i62   on demo.t1 (i6,i2);
create index demo.t1i765  on demo.t1 (i7,i6,i5);

-- insert 10M rows 
-- note: the pages for the five indexes will be intermixed in the table space 
-- and each index will be fragmented
insert into demo.t1 with q(a) as (values 1 union all select a+1 from q where a<10000000)
  select -a,mod(a,1237),mod(-a,251),mod(a,353),mod(-a,100),mod(a,257),mod(-a,511) from q;
commit;

connect reset;

转载自原文链接, 如需删除请联系管理员。

原文链接:DB2 优化 RUNSTATS:排除索引碎片故障,转载请注明来源!

0