楼主: zhiliyang

[精华] 请教两个DB2上的两个隔离/锁相关的问题

[复制链接]
论坛徽章:
6
2010新春纪念徽章
日期:2010-03-01 11:21:012013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11沸羊羊
日期:2015-03-04 14:43:432015年新春福章
日期:2015-03-06 11:57:31
31#
发表于 2009-8-6 11:04 | 只看该作者
For the #1 question, in spite of the diffenrent format of lock report between LUW and mainframe, I can conclude that the timeout/suspension occured on the data row(03000500010001000000000052), which is qualified by C1=11. That is, the second select query needs to lock the row, which is the real important point for this question.
In theory, C1 =22 OR C1 =33, or C1 IN (22,33) re-written by DB2 optimizer, I mean IN LIST predicate, is indexable and stage 1 (sargable), I guess it is so called index-sargable, mentioned in the previous post. In mainframe world, all indexable is sargable, but not all sargable is indexable. I believe most likely, it is still true in LUW world, because the mainframe and LUW optimizers are pretty close.
So, I assume C1 =22 OR C1 =33 is indexable and sargable, and thus not needs to scan/lock the data row(03000500010001000000000052).
Then I conclude there must be another mechanism to force DB2 to do table scan, but not shown in the explain result,  puzzled.
Now, I suggest the post owner to insert more records into the base table, for example 20 records totally, to retry this test, please. Just my guess.

[ 本帖最后由 Pythagoras 于 2009-8-6 11:25 编辑 ]

使用道具 举报

回复
招聘 : c/c++研发
论坛徽章:
45
技术图书徽章
日期:2014-03-10 14:09:192012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-01-04 11:51:22ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15现任管理团队成员
日期:2011-05-07 01:45:082011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:152011新春纪念徽章
日期:2011-01-25 15:41:50
32#
发表于 2009-8-6 11:37 | 只看该作者
sargable index predicate means scanning all records in the index to find a match.
another two types of predicates are start/stop key predicate, and residual predicate:
    * Range delimiting predicates are those used to bracket an index scan; they provide start or stop key values for the index search. These predicates are evaluated by the index manager.
    * Index sargable predicates are not used to bracket a search, but are evaluated from the index if one is chosen, because the columns involved in the predicate are part of the index key. These predicates are also evaluated by the index manager.
    * Data sargable predicates are predicates that cannot be evaluated by the index manager, but can be evaluated by Data Management Services (DMS). Typically, these predicates require the access of individual rows from a base table. If necessary, DMS will retrieve the columns needed to evaluate the predicate, as well as any others to satisfy the columns in the SELECT list that could not be obtained from the index.
    * Residual predicates are those that require I/O beyond the simple accessing of a base table. Examples of residual predicates include those using quantified subqueries (subqueries with ANY, ALL, SOME, or IN), or reading LONG VARCHAR or large object (LOB) data that is stored separately from the table. These predicates are evaluated by Relational Data Services (RDS) and are the most expensive of the four categories of predicates.

使用道具 举报

回复
论坛徽章:
9
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:19:10ITPUB9周年纪念徽章
日期:2010-10-08 09:31:22ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:152013年新春福章
日期:2013-02-25 14:51:24
33#
发表于 2009-8-6 12:02 | 只看该作者
基本同意的unixnewbie分析,
从explain中看,db2 认为 in list 是一个 index sargable precicates。
index sargable 应该是在做index scan时就可以apply predicates以减小data page的fetch。
否则就像楼主说的那跟table scan没区别了,还多了一个index scan。

不过还是有两个疑问:
1、照unixnewbie的分析,应该是index node的lock wait,为何db2pd 显示的却是data row的lock wait。
2、对于in list的操作,db2 为何认为是index sargable predicates呢,这样不是降低效率了吗?难道是表不够大,
如果可以,请楼主把表增加到1W条记录以上,看看对in list的操作会不会改变,谢谢。



以下是ibm 对于in-list的解释(这段话是db2 for z/os里的,他这里的matching index scans类似于我们start key,stop key):

An IN-list index scan is a special case of the matching index scan, in which a single indexable IN predicate is used as a matching equal predicate.

You can regard the IN-list index scan as a series of matching index scans with the values in the IN predicate being used for each matching index scan. The following example has an index on (C1,C2,C3,C4) and might use an IN-list index scan:

SELECT * FROM T
  WHERE C1=1 AND C2 IN (1,2,3)
    AND C3>0 AND C4<100;

The plan table shows MATCHCOLS = 3 and ACCESSTYPE = N. The IN-list scan is performed as the following three matching index scans:

(C1=1,C2=1,C3>0), (C1=1,C2=2,C3>0), (C1=1,C2=3,C3>0)

使用道具 举报

回复
论坛徽章:
18
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:52
34#
发表于 2009-8-6 14:26 | 只看该作者
原帖由 mdkii 于 6/8/2009 14:02 发表
基本同意的unixnewbie分析,
从explain中看,db2 认为 in list 是一个 index sargable precicates。
index sargable 应该是在做index scan时就可以apply predicates以减小data page的fetch。
否则就像楼主说的那跟table scan没区别了,还多了一个index scan。

不过还是有两个疑问:
1、照unixnewbie的分析,应该是index node的lock wait,为何db2pd 显示的却是data row的lock wait。
2、对于in list的操作,db2 为何认为是index sargable predicates呢,这样不是降低效率了吗?难道是表不够大,
如果可以,请楼主把表增加到1W条记录以上,看看对in list的操作会不会改变,谢谢。


对于你的疑问,我的看法
1. 我的猜想是因为DB2里LOCK所apply的对象(Lock Object Type)除了internal的一些object (比如package)外就只有Row和TABLE(对于普通的Table),对于MDC则多了block level,对于partitioned table则多了table partition level。其没有一种类型是index key lock。所以当需要lock index key record时,因为index key record与ROW是一一对应(当然pseduo delete的key除外)的,所以锁ROW即锁了index key record。

2. DB2的optimizor算法我们无从知道。我个人focus在怎样影响DB2 optimizor方面努力。

使用道具 举报

回复
论坛徽章:
6
2010新春纪念徽章
日期:2010-03-01 11:21:012013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11沸羊羊
日期:2015-03-04 14:43:432015年新春福章
日期:2015-03-06 11:57:31
35#
发表于 2009-8-6 15:34 | 只看该作者
From wangzhonnew's reply, I know there are some diffenrence in respect of predicate type between LUW and mainframe. But anyway, C1 =22 OR C1 =33 is an index sargable predicate, and should be evaluated by the index manager, no data access is needed for unqualified entries.
And for mdkii's reply,
1. DB2 only locks data, not index entries, at least for DB2 z/OS. I believe same behavior for DB2 LUW.
2. Index sargable predicate is effective enough, and should be the correct choice for DB2 optimizer.

But, if too few records in the table, the optimizer will choose table scan instead of index, based on cost, and this should be shown in the explain result. Unfortunately, we didn't see table scan in the explain result  for this case.
At last, for DB2 z/OS, it is possible that index scan shown in the explain result, but real access path is table scan. I mean, DB2 optimizer originally chooses to use index access, but finally have to fall into table scan access, under some restrict conditions. For DB2 LUW, I don't whether it is possible.

I still suggest the post owner to increase the total cardinality of the table and retry. The purpose is, avoid DB2 fall into table scan, because with many more records, table scan is much more expensive than index. And let us see the result, to verify the guess.

[ 本帖最后由 Pythagoras 于 2009-8-6 15:44 编辑 ]

使用道具 举报

回复
论坛徽章:
0
36#
 楼主| 发表于 2009-8-6 15:56 | 只看该作者
原帖由 unixnewbie 于 2009-8-6 10:46 发表


证明DB2需要读取整个INDEX,所以肯定要“经过”你在另一进程中刚刚插入或修改的数据所对应在index中的那个record。由于DB2中的行锁只在ROW或TABLE上,所以锁ROW data也就是mapping到锁住index中对应的那个Record。


彻底Agree了。
另外用了一个hierarchy表,里面3个column:PKEY(CHAR 3), CKEY(CHAR 3), NUM(SMALL INT)
指定PKEY,CKEY为key.

插入若干数据后,在一个窗口执行
+C UPDATE HIERARCHY SET NUM = 111 WHERE PKEY = 'AAA' AND CKEY = 'BBB';

然后再在另外一个窗口执行
select pkey,ckey
from hierarchy
where         (pkey='BBB' AND  ckey ='CCC')
OR        (PKEY = 'CCC' AND CKEY = 'EEE')
成功返回。


access plan为:
  1. Original Statement:
  2. ------------------
  3. select pkey,ckey
  4. from hierarchy
  5. where (pkey='BBB' AND ckey ='CCC')OR(PKEY = 'CCC' AND CKEY = 'EEE')


  6. Optimized Statement:
  7. -------------------
  8. SELECT Q1.PKEY AS "PKEY", Q1.CKEY AS "CKEY"
  9. FROM YANGLU.HIERARCHY AS Q1
  10. WHERE (((Q1.PKEY = 'BBB') AND (Q1.CKEY = 'CCC')) OR ((Q1.PKEY = 'CCC') AND
  11.         (Q1.CKEY = 'EEE')))

  12. Access Plan:
  13. -----------
  14.         Total Cost:                 0.0213858
  15.         Query Degree:                1

  16.         Rows
  17.        RETURN
  18.        (   1)
  19.         Cost
  20.          I/O
  21.          |
  22.         1.75
  23.        IXSCAN
  24.        (   2)
  25.       0.0213858
  26.           0
  27.          |
  28.           7
  29.    INDEX: SYSIBM  
  30. SQL090721132539560

  31. ....
  32.         2) IXSCAN: (Index Scan)
  33.                 Cumulative Total Cost:                 0.0213858
  34.                 Cumulative CPU Cost:                 66257.4
  35.                 Cumulative I/O Cost:                 0
  36.                 Cumulative Re-Total Cost:         0.00994012
  37.                 Cumulative Re-CPU Cost:         30796.4
  38.                 Cumulative Re-I/O Cost:         0
  39.                 Cumulative First Row Cost:         0.0169107
  40.                 Estimated Bufferpool Buffers:         1

  41.                 Arguments:
  42.                 ---------
  43.                 MAXPAGES: (Maximum pages for prefetch)
  44.                         ALL
  45.                 PREFETCH: (Type of Prefetch)
  46.                         NONE
  47.                 ROWLOCK : (Row Lock intent)
  48.                         NEXT KEY SHARE
  49.                 SCANDIR : (Scan Direction)
  50.                         FORWARD
  51.                 TABLOCK : (Table Lock intent)
  52.                         INTENT SHARE

  53.                 Predicates:
  54.                 ----------
  55.                 2) Sargable Predicate
  56.                         Comparison Operator:                 Not Applicable
  57.                         Subquery Input Required:         No
  58.                         Filter Factor:                         0.0535714

  59.                         Predicate Text:
  60.                         --------------
  61.                         (((Q1.PKEY = 'BBB') AND (Q1.CKEY = 'CCC')) OR
  62.                                 ((Q1.PKEY = 'CCC') AND (Q1.CKEY = 'EEE')))


  63.                 Input Streams:
  64.                 -------------
  65.                         1) From Object SYSIBM.SQL090721132539560

  66.                                 Estimated number of rows:         7
  67.                                 Number of columns:                 3
  68.                                 Subquery predicate ID:                 Not Applicable

  69.                                 Column Names:
  70.                                 ------------
  71.                                 +Q1.$RID$+Q1.CKEY+Q1.PKEY


  72.                 Output Streams:
  73.                 --------------
  74.                         2) To Operator #1

  75.                                 Estimated number of rows:         1.75
  76.                                 Number of columns:                 2
  77.                                 Subquery predicate ID:                 Not Applicable

  78.                                 Column Names:
  79.                                 ------------
  80.                                 +Q2.CKEY+Q2.PKEY
复制代码


然而如果在第一个update的sql里面修改了PKEY/CKEY的值的话,where ... or ...这个语句的access plan里面的Sargable Predicate会导致整个index检索和对比,从而又等待了一个行锁上。

使用道具 举报

回复
论坛徽章:
0
37#
 楼主| 发表于 2009-8-6 16:09 | 只看该作者
这个执行计划可能更贴近最开始的情况:

  1. Original Statement:
  2. ------------------
  3. select pkey,ckey
  4. from hierarchy
  5. where pkey in ('BBB','CCC','DDD')


  6. Optimized Statement:
  7. -------------------
  8. SELECT Q3.PKEY AS "PKEY", Q3.CKEY AS "CKEY"
  9. FROM YANGLU.HIERARCHY AS Q3
  10. WHERE Q3.PKEY IN ('BBB', 'CCC', 'DDD')

  11. Access Plan:
  12. -----------
  13.         Total Cost:                 0.0176306
  14.         Query Degree:                1

  15.         Rows
  16.        RETURN
  17.        (   1)
  18.         Cost
  19.          I/O
  20.          |
  21.          3.5
  22.        IXSCAN
  23.        (   2)
  24.       0.0176306
  25.           0
  26.          |
  27.           7
  28.    INDEX: SYSIBM  
  29. SQL090721132539560


  30. .....

  31.         2) IXSCAN: (Index Scan)
  32.                 Cumulative Total Cost:                 0.0176306
  33.                 Cumulative CPU Cost:                 54623
  34.                 Cumulative I/O Cost:                 0
  35.                 Cumulative Re-Total Cost:         0.00618489
  36.                 Cumulative Re-CPU Cost:         19162
  37.                 Cumulative Re-I/O Cost:         0
  38.                 Cumulative First Row Cost:         0.0136769
  39.                 Estimated Bufferpool Buffers:         1

  40.                 Arguments:
  41.                 ---------
  42.                 MAXPAGES: (Maximum pages for prefetch)
  43.                         ALL
  44.                 PREFETCH: (Type of Prefetch)
  45.                         NONE
  46.                 ROWLOCK : (Row Lock intent)
  47.                         NEXT KEY SHARE
  48.                 SCANDIR : (Scan Direction)
  49.                         FORWARD
  50.                 TABLOCK : (Table Lock intent)
  51.                         INTENT SHARE

  52.                 Predicates:
  53.                 ----------
  54.                 3) Sargable Predicate
  55.                         Comparison Operator:                 In List (IN), evaluated by binary search (list sorted at compile-time)
  56.                         Subquery Input Required:         No
  57.                         Filter Factor:                         0.5

  58.                         Predicate Text:
  59.                         --------------
  60.                         Q3.PKEY IN ('BBB', 'CCC', 'DDD')


  61.                 Input Streams:
  62.                 -------------
  63.                         1) From Object SYSIBM.SQL090721132539560

  64.                                 Estimated number of rows:         7
  65.                                 Number of columns:                 3
  66.                                 Subquery predicate ID:                 Not Applicable

  67.                                 Column Names:
  68.                                 ------------
  69.                                 +Q3.PKEY(A)+Q3.CKEY(A)+Q3.$RID$


  70.                 Output Streams:
  71.                 --------------
  72.                         2) To Operator #1

  73.                                 Estimated number of rows:         3.5
  74.                                 Number of columns:                 2
  75.                                 Subquery predicate ID:                 Not Applicable

  76.                                 Column Names:
  77.                                 ------------
  78.                                 +Q4.PKEY(A)+Q4.CKEY(A)
复制代码


在uncommit Update的record没有修改index 所在column的时候,sargable predicate on index scan是能够正常返回而不等待锁的

使用道具 举报

回复
论坛徽章:
9
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:19:10ITPUB9周年纪念徽章
日期:2010-10-08 09:31:22ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:152013年新春福章
日期:2013-02-25 14:51:24
38#
发表于 2009-8-7 10:10 | 只看该作者
我把测试表数据加到1w后,终于见到我们想见的。

in list 操作变成了 start key, stop key。

因此,我认为 db2 选择 index total scan 是因为表里的记录太少,做index direct lookup的代价大于
index total scan。

当表里记录数增加到一定数量后,db2 就选择start key stop key (index direct lookup) 方式了。
在这种情况下,update就不在阻塞select了。
这也再次证明 unixnewbie的分析是正确的。

对于楼主的后面两个例子,我认为是不是因为没有update index key,
因此update操作没有对index node 加写锁,所以select操作可以scan index。

感谢大家的热情参与,让我学了不少东西。
包括 unixnewbie 的精彩分析,  
Pythagoras  的热情参与(虽然你是做主机的,但能够参与到开放平台的讨论当中很值得表扬)
还有楼主提供这么好的例子。。。。。

使用道具 举报

回复
论坛徽章:
233
天枰座
日期:2016-02-02 09:36:332012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-06-22 19:28:30现任管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:拳击
日期:2011-04-08 16:56:552011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
39#
发表于 2009-8-7 11:06 | 只看该作者
来迟了。

只能射精了

使用道具 举报

回复
论坛徽章:
0
40#
 楼主| 发表于 2009-8-7 17:57 | 只看该作者
原帖由 mdkii 于 2009-8-4 17:56 发表
对于问题一,牛博士的书里有很好的解释。
DB2默认会加锁是在apply predicate 之前。
如果你要改变这个行为,请使用注册变量
DB2_EVALUNCOMMITTED




mdkii和unixnewbie随便说两句话偶都得google上一整子,加翻半天书。
果然是牛13啊。

刚刚按两位的推荐验证了牛博士书上的DB2_EVALUNCOMMITTED,DB2_SKIPDELETED, DB2_SKIPINSERTED三个变量的作用。
叹服叹服。


To:Pythagoras
老兄慢走啊,偶也是跑在大机上的。
回头还得多多请教了

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表