DB2数据库中提高INSERT性能详解

本文详细探讨了如何优化DB2数据库中的INSERT操作,包括语句准备、数据传输、存储定位、缓冲池和I/O管理、锁管理、日志记录以及提交策略。建议使用LOAD和批量INSERT、调整DB2配置参数、使用参数标记和数组插入等方法提高性能。还讨论了索引维护、提交频率和日志写入对性能的影响,以及在并发环境下的锁冲突问题。
摘要由CSDN通过智能技术生成

INSERT 处理过程概述

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

  在客户机准备 语句。对于动态 SQL,在语句执行前就要做这一步,此处的性能是很重要的;对于静态 SQL,这一步的性能实际上关系不大,因为语句的准备是事先完成的。在客户机,将要插入的行的各个 列值组装起来,发送到 DB2 服务器。 DB2 服务器确定将这一行插入到哪一页中。DB2 在用于该页的缓冲池中预留一个位置。假如 DB2 选定的是个已有的页,那么就需要读磁盘;假如使用一个新页,则要在表空间(假如是SMS,也就是系统管理存储的表空间)中为该页物理地分配空间。插入了新行的每一页最后都要从缓冲池写入到磁盘。在目标页中对该行进行格式化,并获得该行上的一个X(exclusive,独占的) 行锁。将反映该 insert 的一条记录写入到日志缓冲区中。

  最后提交包含该 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 的运行速度提高数倍。(在静态

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值