Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103635749
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-04-14 13:13:09

 来源:数据库用户 

注意

在 V7 中,存在涉及 insert 和键锁的并发问题,但是在 V8 中,由于提供了 type-2 索引,这些问题实际上已经不见了。如果要迁移到 V8 中来,那么应该确保使用带 CONVERT 关键字的 REORG INDEXES 命令,以便将索引从 type-1 转换为 type-2。

在 V7 中,插入过程中可能使用 W 或 NW 锁,但是在 V8 中只有在使用了 type-1 索引或者隔离级别为 RR 的情况下才会出现这两种锁。因此,应尽可能避免这两种情况。

一条 insert 所据有的锁(通常是一个 X 锁)通常不会受隔离级别的影响。例如,使用隔离级别 UR 不会阻止从插入的行上获得锁。然而,如果使用了 INSERT ... SELECT,则隔离级别将影响从 SELECT 获得的锁。

6. 日志记录

缺省情况下,每条 insert 都会被记录下来,以用于恢复。日志记录首先被写到内存中的日志缓冲池,然后再写到日志文件,通常是在日志缓冲池已满或者发生了一次提交时写到日志文件的。对批量插入的日志记录的优化实际上就是最小化日志记录写的次数,以及使写的速度尽可能快。

这里首先考虑的是日志缓冲池的大小,这由数据库配置参数 LOGBUFSZ 来控制。该参数缺省值为 8 页或 32 K,这与大多数批量插入所需的理想日志缓冲池大小相比要小些。举个例子,对于一个批量插入,假设对于每一行的日志内容有 200 字节,则在插入了 160 行之后,日志缓冲池就将被填满。如果要插入 1000 行,因为日志缓冲池将被填满几次,再加上提交,所以大概有 6 次日志写。如果将 LOGBUFSZ 的值增加到 64 页(256K)或者更大,缓冲池就不会被填满,这样的话对于该批量插入就只有一次日志写(在提交时)。通过使用更大的 LOGBUFSZ 可以获得大约 13% 的性能提升。较大日志缓冲池的不利之处是,紧急事故恢复所花的时间可能要稍微长一点。

减少日志写的另一种可能性是对新行要插入到的那个表使用“ALTER TABLE ACTIVATE NOT LOGGED INITIALLY”(NLI)。如果这样做了,那么在该工作单元内不会记录任何 insert 操作,但是这里存在两个与 NLI 有关的重要问题:

如果有一条语句失败,那么这个表将被标记为不可访问的,并且需要被删除掉。这与其他恢复问题(请参阅 SQL Reference 关于 Create Table 的讨论)一起使得 NLI 在很多情况下不能成为可行的方法。

在工作单元最后进行的提交,必须等到在此工作单元内涉及的所有脏页都被写到磁盘之后才能完成。这意味着这种提交要占用大量的时间。如果没有积极地进行页清除,那么在使用 NLI 的情况下,Insert 加上提交所耗费的总时间要更长一些。将 NLI 与积极的页清除一起使用的时候,可以大大减少耗时。如果使用 NLI,就要瞪大眼睛盯紧提交操作所耗费的时间。

至于提高日志写的速度,有下面一些可能性:

将日志与新行所要插入到的表分别放在不同的磁盘上。

在操作系统层将日志分放到多个磁盘。

考虑为日志使用原始设备(raw device),但是要注意,这样管理起来要更困难些。

避免使用 RAID 5,因为它不适合于写密集型(write-intensive)活动。

7. 提交

提交迫使将日志记录写到磁盘上,以保证提交的插入肯定会存在于数据库中,并且释放新行上的锁。这些都是有价值的活动,但是因为 Commit 总是要牵涉到同步 I/O(对于日志),而 insert 则不会,所以 Commit 的开销很容易高于 insert 的开销。因此,在进行批量插入时,每一行都提交一次的做法对于性能来说是很糟糕的,所以应确保不使用自动提交(对于 CLI 和 CLP 来说缺省情况正是如此)。建议大约每 1000 行提交一次:当每 1000 行而不是一两行提交一次时,性能可以提高大概 10 倍。不过,一次提交多于 1000 行只能节省少量的时间,但是一旦出现失败,恢复起来所花的时间要更多。

对上述方法的一种修正:如果 MINCOMMIT 数据库配置参数的值大于 1 (缺省值),则 DB2 就不必对每次 commit 都进行一次同步 I/O,而是等待,并试图与一组事件一起共享日志 I/O。对于某些环境来讲,这样做是有好处,但是对于批量插入常常没有作用,甚至有负作用,因此,如果要执行的关键任务是批量插入,就应该让 MINCOMMIT 的值保持为 1。

阅读(245) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~