互联网服务数据库

Sql调优,诡异的索引

如下Sql:
SELECT COUNT(DISTINCT C.ACT_NBR)AS TOTAL  FROM ESPDB.F_ACCOUNT AS C WHERE C.CST_NBR =cast(? as bigint)AND C.ORG_NBR =cast(? as smallint) AND C.AVL_CRL <=?
由于存在Distinct,所以会排序,现在目标是想办法消除排序

建立了索引(CST_NBR,ORG_NBR,AVL_CRL,ACT_NBR)


理论上,应该会消除distinct排序,可是看执行计划,竟然还是会排序,哪位大侠知道原因么??


              Rows         
            Operator        
              (ID)         
              Cost         

               1            
            RETURN         
             ( 1)           
            9.54199         
              |            
               1            
             GRPBY         
             ( 2)           
            9.54159         
              |            
           0.254977         
            TBSCAN         
             ( 3)           
           9.54145         
              |            
           0.254977         
             SORT           
             ( 4)           
           9.54072         
                   /                
    0.254977     631423     
     IXSCAN     Table:      
      ( 6)      ESPDB      
    7.60982     F_ACCOUNT   
      |                     
    166072                  
Index:                     
ESPDB                     
ACCOUNT_INDEX              




诡异的索引,诡异的排序~
参与11

10同行回答

xxzmxxxxzmxx软件开发工程师招行软件中心
回复 8# mdkii 这个例子举得好。我是看快照,发现有大量排序移除,平均30%左右吧。现在消除了所有排序,发现cpu还是有点高。看来排序也不一定是引起cpu高耗的原因。显示全部
回复 8# mdkii

这个例子举得好。
我是看快照,发现有大量排序移除,平均30%左右吧。现在消除了所有排序,发现cpu还是有点高。看来排序也不一定是引起cpu高耗的原因。收起
互联网服务 · 2011-11-07
浏览602
wangzhonnewwangzhonnew软件工程师IBM Canada Ltd.
索引就是B+树啦,楼上的大学计算机课程中早应该学过的吧:lol显示全部
索引就是B+树啦,楼上的大学计算机课程中早应该学过的吧:lol收起
IT分销/经销 · 2011-11-02
浏览610
wp28556259wp28556259软件架构设计师CMBC
回复 8# mdkii     嗯,讲得很好,谢谢~显示全部
回复 8# mdkii


    嗯,讲得很好,谢谢~收起
银行 · 2011-11-02
浏览607
mdkiimdkii软件开发工程师bocn
复合索引是按每个字段排序的,但都是先保证前一个字段排序后才会对第二个字段排序。比如有个复合索引(A,B)顺序是这样的(1,1),(1,2),(1,3),(2,1),(2,2),(2,3)。但条件为 A=1 order by B时,扫描出来的记录是 (1,1),(1,2),(1,3),自然是按B排序的。但条件为 A>=1 order by B时,扫描...显示全部
复合索引是按每个字段排序的,但都是先保证前一个字段排序后才会对第二个字段排序。
比如有个复合索引(A,B)顺序是这样的
(1,1),(1,2),(1,3),(2,1),(2,2),(2,3)。
但条件为 A=1 order by B时,扫描出来的记录是 (1,1),(1,2),(1,3),自然是按B排序的。
但条件为 A>=1 order by B时,扫描出来的记录是 (1,1),(1,2),(1,3),(2,1),(2,2),(2,3),B列是乱序的。

索引的资料比较少,我也是刚入门。
这里推荐一本还不错的。
Wiley,.Relational.Database.Index.Design.and.the.Optimizers.pdf
网上可以下载。收起
银行 · 2011-11-02
浏览626
wp28556259wp28556259软件架构设计师CMBC
回复 5# mdkii     我上网搜了一下DB2索引相关的资料,感觉都是一些很浅的。感觉MKDII对索引很有研究,有没有什么资料或者好贴呀?分享一下~给大家学习学习~{:2_42:}显示全部
回复 5# mdkii


    我上网搜了一下DB2索引相关的资料,感觉都是一些很浅的。感觉MKDII对索引很有研究,有没有什么资料或者好贴呀?分享一下~给大家学习学习~{:2_42:}收起
银行 · 2011-11-02
浏览557
wp28556259wp28556259软件架构设计师CMBC
回复 3# mdkii     “就是索引的第三列 AVL_CRL 上有一个范围比较,这样通过索引扫描出来的结果不能保证是按ACT_NBR排序的。”请教一下,复合索引的存储结构不是按照列的顺序依次顺序排列吗...显示全部
回复 3# mdkii


    “就是索引的第三列 AVL_CRL 上有一个范围比较,这样通过索引扫描出来的
结果不能保证是按ACT_NBR排序的。”

请教一下,复合索引的存储结构不是按照列的顺序依次顺序排列吗收起
银行 · 2011-11-02
浏览620
mdkiimdkii软件开发工程师bocn
你这个sql有distinct和rownumber在里面,要看一下执行计划才能确定是否能够用索引扫描来代替排序。建议你先用db2advis 看看这句话需要加什么样的索引。有时候排序是不可避免的,而且索引扫描并不总是比排序效率高。纯粹的想从避免排序来优化SQL是没什么意义的。...显示全部
你这个sql有distinct和rownumber在里面,
要看一下执行计划才能确定是否能够用索引扫描来代替排序。
建议你先用db2advis 看看这句话需要加什么样的索引。
有时候排序是不可避免的,而且索引扫描并不总是比排序效率高。
纯粹的想从避免排序来优化SQL是没什么意义的。收起
银行 · 2011-11-01
浏览599
xxzmxxxxzmxx软件开发工程师招行软件中心
回复 3# mdkii    真的是这样,恍然大悟,多谢!另外请教,如果是如下的sql,要想避免ORDER BY C.ACT_TYP, C.ACT_NBR 这两列上的排序,那么索引该如何建立呢?     SELECT DISTINCT C.BRF_NAM AS CLT_NAM, C.EMP_NBR AS CLT_EMP_NBR,    ...显示全部
回复 3# mdkii


   真的是这样,恍然大悟,多谢!
另外请教,如果是如下的sql,要想避免ORDER BY C.ACT_TYP, C.ACT_NBR 这两列上的排序,那么索引该如何建立呢?

     SELECT DISTINCT C.BRF_NAM AS CLT_NAM, C.EMP_NBR AS CLT_EMP_NBR,
             C.ORG_NBR AS ORG_NBR, C.ACT_NBR AS ACT_NBR, C.CLT_NBR AS
             CLT_NBR, C.ACT_TYP AS ACT_TYP, C.ACT_STS AS ACT_STS,
             C.ACT_CRL AS ACT_CRL, C.AVL_CRL AS AVL_CRL, C.TMP_CRL AS
             TMP_CRL, C.TMP_CRL_STR_DTE AS TMP_CRL_STR_DTE,
             C.TMP_CRL_END_DTE AS TMP_CRL_END_DTE, C.PER_CRL AS
             PER_CRL, ROWNUMBER()OVER(
     ORDER BY C.ACT_TYP, C.ACT_NBR)AS ROWNUM
     FROM ESPDB.F_ACCOUNT AS C
     WHERE C.CST_NBR = 9900000498 AND C.ORG_NBR =156 AND C.AVL_CRL <=5000收起
互联网服务 · 2011-10-31
浏览586
mdkiimdkii软件开发工程师bocn
因为在你的索引里,排序列之前有一个range predicate。就是说你要按索引的第四列 ACT_NBR 排序,但是在它之前,就是索引的第三列 AVL_CRL 上有一个范围比较,这样通过索引扫描出来的结果不能保证是按ACT_NBR排序的。你把排序列ACT_NBR放到第三列,前两列都是等值比较,这样通过索引...显示全部
因为在你的索引里,排序列之前有一个range predicate。
就是说你要按索引的第四列 ACT_NBR 排序,但是在它之前,
就是索引的第三列 AVL_CRL 上有一个范围比较,这样通过索引扫描出来的
结果不能保证是按ACT_NBR排序的。
你把排序列ACT_NBR放到第三列,前两列都是等值比较,
这样通过索引扫描出来的记录肯定是按ACT_NBR排列的。
如果要用索引避免排序,一定要保证排序列前都是等值比较。收起
银行 · 2011-10-31
浏览604
xxzmxxxxzmxx软件开发工程师招行软件中心
搞定了, 可是想不通,为什么调整顺序,就可以避免排序了?索引顺序改为如下:(CST_NBR,ACT_NBR,ORG_NBR,AVL_CRL)显示全部
搞定了, 可是想不通,为什么调整顺序,就可以避免排序了?

索引顺序改为如下:(CST_NBR,ACT_NBR,ORG_NBR,AVL_CRL)收起
互联网服务 · 2011-10-31
浏览590

提问者

xxzmxx
软件开发工程师招行软件中心

相关问题

相关资料

相关文章

问题状态

  • 发布时间:2011-10-31
  • 关注会员:1 人
  • 问题浏览:7175
  • 最近回答:2011-11-07
  • X社区推广