当前位置: 首页 > 图文教程 > 数据库 > DB2 > 在DB2中提高INSERT性能的技巧(1)

DB2
在Linux虚拟机上安装 DB2 9
DB2 9励精图强 Viper 2续写传奇
DB2返回SQLCODE -818 错误
DB2未来版“Viper 2” :为IT敏捷加速
解析:DB2 无限活动日志策略的实用技巧
SQL Server和MySQL的安全性分析
DB2数据库归档日志的管理方案
实例解析IBM DB2的数据复制、迁移方法
备份恢复DB2数据库步骤
DB2 9部署定制的安全性插件
DB2 Web 服务提供者的安全性
DB2无限活动日志策略从介绍到实用技巧
实现对 DB2 UDB 的低层访问控制
DB2数据库安全涉及的问题
关于DB2 数据库授权的研究
DB2 数据库身份验证基础
监控 DB2 活动之捕获事件监控数据
使用重定向恢复克隆 DB2 数据库
监控 DB2 活动之捕获快照数据
DB2 数据库特权授予的方法和技巧

在DB2中提高INSERT性能的技巧(1)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 136 ::
收藏到网摘: n/a

正在看的db2教程是:在DB2中提高INSERT性能的技巧(1)。

INSERT 处理过程概述

首先让我们快速地看看插入一行时的处理步骤。这些步骤中的每一步都有优化的潜力,对此我们在后面会一一讨论。

  1. 在客户机准备 语句。对于动态 SQL,在语句执行前就要做这一步,此处的性能是很重要的;对于静态 SQL,这一步的性能实际上关系不大,因为语句的准备是事先完成的。
  2. 在客户机,将要插入的行的各个 列值组装起来,发送到 DB2 服务器。
  3. DB2 服务器确定将这一行插入到哪一页中。
  4. DB2 在 用于该页的缓冲池中预留一个位置。如果 DB2 选定的是一个已有的页,那么就需要读磁盘;如果使用一个新页,则要在表空间(如果是SMS,也就是系统管理存储的表空间)中为该页物理地分配空间。插入了新行的每一页最后都要从缓冲池写入到磁盘。
  5. 在目标页中对该行进行格式化,并获得该行上的一个X(exclusive,独占的) 行锁。
  6. 将反映该 insert 的一条记录写入到日志缓冲区中。
  7. 最后提交包含该 insert 的事务,如果这时日志缓冲区中的记录还没有被写入日志文件的话,则将这些记录写到日志文件中。
此外,还可能发生很多类型的附加处理,这取决于数据库配置,例如,索引或触发器的存在。这种额外的处理对于性能来说也是意义重大的,我们在后面会讨论到。

insert 的替代方案

在详细讨论 insert 的优化之前,让我们先考虑一下 insert 的两种替代方案:load 和 import。import 实用程序实际上是 SQL INSERT 的一个前端,但它的某些功能对于您来说也是有用的。load 也有一些有用的额外功能,但是我们使用 load 而不使用 insert 的主要原因是可以提高性能。

load 直接格式化数据页,而避免了由于插入导致的对每一行进行处理的大部分开销(例如,日志记录在这里实际上是消除了)。而且,load 可以更好地利用多处理器机器上的并行性。在 V8 load 中有两个新功能,它们对于 load 成为 insert 的替代方案有着特别的功效,这两个功能是:从游标装载和从调用层接口(CLI)应用程序装载。

从游标装载


这种方法可用于应用程序的程序代码(通过 db2Load API),或用于 DB2 脚本。下面是后一种情况的一个例子:
declare staffcursor cursor forselect * from staff;
load from staffcursor of cursor insert into myschema.new_staff;

这两行可以用下面一行替代:
insert into myschema.new_staff select * from staff
同等效的 INSERT ... SELECT 语句相比,从游标装载几乎可以提高 20% 的性能。

从 CLI 装载


这种方法显然只限于调用层接口(CLI)应用程序,但是它非常快。这种技巧非常类似于数组插入,DB2 附带了这样的示例,使用 load 时的速度是使用经过完全优化的数组插入时的两倍,几乎要比未经优化的数组插入快 10 倍。

所有 insert 可以改进的地方

让我们看看插入处理的一些必要步骤,以及我们可以用来优化这些步骤的技巧。

1. 语句准备


作为一条 SQL 语句,INSERT 语句在执行之前必须由 DB2 进行编译。这一步骤可以自动发生(例如在 CLP 中,或者在一次 CLI SQLExecDirect 调用中),也可以显式地进行(例如,通过一条 SQL Prepare、CLI SQLPrepare 或 JDBC prepareStatement 语句)。该编译过程牵涉到授权检查、优化,以及将语句转化为可执行格式时所需的其他一些活动。在编译语句时,语句的访问计划被存储在包缓存中。

如果重复地执行相同的 INSERT 语句,则该语句的访问计划(通常)会进入到包缓存中,这样就免除了编译的开销。然而,如果 insert 语句对于每一行有不同的值,那么每一条语句都将被看成是惟一的,必须单独地进行编译。因此,将像下面这样的重复语句:
insert into mytable values (1, 'abc')
insert into mytable values (2, 'def')

等等,
换成带有参数标记的语句,一次准备,重复执行,这样做是十分可取的:
insert into mytable values (?, ?)

使用参数标记可以让一系列的 insert 的运行速度提高数倍。(在静态 SQL 程序中使用主机变量也可以获得类似的好处。)

2. 发送列值到服务器


可以归为这一类的优化技巧有好几种。最重要的一种技巧是在每条 insert 语句中包括多行,这样就可以避免对于每一行都进行客户机-服务器通信,同时也减少了 DB2 开销。可用于多行插入的技巧有: