“仅索引” 更新和删除的秘密
2009-11-16 00:00:00 来源:WEB开发网对于新访问路径的 1700 个 RID 中的每一个 RID,DB2 将读取表并且可能进行 1700 次 GET PAGE 和 1700 次读 I/O。我们预期 DB2 在每个接触的表页上获得一个 X 锁。这次达到了预期:它确实这样做。为什么?因为 DB2 完全确定它将真正地执行 DELETE。没有任何进一步的谓词应用于表行。使用索引数据,行已经完全限制。
DELETE 不是 “仅索引” 的;行限定是 “仅索引” 的。我们知道,不管是 UPDATE 还是 DELETE,都不可能实现真正的 “仅索引”。因此,DB2 使用 PLAN_TABLE 列为我们提供语句的有用信息。
我们将在四个或五个相邻索引页上读取 400 个相邻的索引行,并找到 1700 个限制的 RID。使用 “仅索引” DELETE,开销是:
1700 次 GET PAGE
1700 次读 I/O
获取 1700 个 X 锁
COMMIT 来释放 1700 个 X 锁。
我们没有任何升级开销;已经将 4401 次跨内存服务调用减少到 1701 次,并且已经将潜在的锁挂起和超时从 4400 次减少到 1700 次。这种新技术的最大收获在于:因为不需要请求另外的 2700 个锁,我们不会被告知 no。
解开谜底
现在我们知道了为什么 PLAN_TABLE 中的 INDEX_ONLY 标志对于 UPDATE 或 DELETE 可以是 Y。并且我们已经看到:向索引添加单个一字节的列能够提升性能。如果这个专栏更长一点的话,我将详细说明为什么添加的列不应该频繁地更新,不应过大而导致过度增加索引页的数目,不应导致索引增加许多层次,以及不应对性能产生影响。
另一个细微差别
DSNZPARM XLKUPDLT(值为 YES、TARGET 和默认值 NO)可能对一些 DB2 子系统有用。请记住,ZPARMS 应用于整个 DB2 子系统,而不仅仅是一个包或一个表空间。将 XLKUPDLT ZPARM 设置为 YES 告知 DB2 立即为为 UPDATE 或 DELETE 读取的每个页获取一个 X 锁,而不管谓词应用是什么。
这种方法消除所有 U 锁到 X 锁的升级开销(以及跨内存服务调用和由此产生的额外超时)。但是,为这个参数使用 YES 意味着您必须非常确信大部分 X 锁都适合的,通过索引谓词完全限定大部分表行,并且应用非索引谓词时不会取消限定。(顺便说一下,如果页上没有任何行限定,那么不友好的 X 锁将立即释放,不会保持到 COMMIT)。
在我们的第一个例子中,使用两行索引,并且 XLKUPDLT 使用 YES,开销为:
2200 次 GET PAGE
2200 次读 I/O
获取 2200 个 X 锁,一次一个
释放 500 个 X 锁,一次一个(在每个没有任何限定行的页上)
一次 COMMIT 来释放 1700 个合适的 X 锁。
ZPARM 值为 YES 时,会带来更多不友好(并且不必要)的 X 锁,从而增加超时的可能性。请记住,该协议适用于 SQL 搜索的 UPDATE 或 DELETE 引用的所有表,甚至是在 WHERE 子句的子选择中命名的表。
第三个选项是 NO 和 YES 之间的折衷。如果为 ZPARM 使用值 TARGET,那么只为 UPDATE 或 DELETE 需要的表请求 YES 协议。NO 协议将用于 SQL 语句中引用的其它表。
应该考虑将 ZPARM 的 TARGET 值用于数据共享环境(它通过良好过滤索引访问数据)。在性能争用/并发环境中,通过不良过滤索引使用表空间扫描或表访问的 UPDATE 或 DELETE 可能会产生破坏性后果。
更多精彩
赞助商链接