SQL优化--强制走索引失效的情况

select count(0) from creditguarantee cg where 1=1

           and cg.createddate>=to_date('2012-02-23','yyyy-MM-dd')
           and cg.createddate<=to_date('2012-02-26','yyyy-MM-dd')   
           and 2=
            (case
              when
                 (select count(0) from creditlevelchange where customerid=cg.customerid and createddate<=to_date('2012-02-26','yyyy-MM-dd'))>0
              then   
                 (select newlevel from creditlevelchange where customerid=cg.customerid and
                   changeid=
                     (select max(changeid) from creditlevelchange where customerid=cg.customerid and createddate<=to_date('2012-02-26','yyyy-MM-dd'))
                  ) 
              else
                 (case
                    when
                     (select count(0) from creditlevelchange where customerid=cg.customerid and createddate>to_date('2012-02-26','yyyy-MM-dd'))>0
                    then   
                     (select oldlevel from creditlevelchange where customerid=cg.customerid and
                       changeid=
                         (select min(changeid) from creditlevelchange where customerid=cg.customerid and createddate>to_date('2012-02-26','yyyy-MM-dd'))
                      )
                    else   
                       cg.creditlevelid 
                 end)
            end)

========================================================================================================
这是开发发过来的sql,完全一样的SQL,在huifu2上面不到1秒能跑出来,在jsjdata0上面要跑3分钟左右。
查看执行计划,可以很清晰的发现问题出在jsjdata0上面没有走索引。creditguarantee这张表上面的列
CREATEDDATE上有一个索引NL_CREDATEDATE,在huifu2上面走了,但是在jsjdata0这里访问creditguarantee却
是走的全表扫描。我第一反应是索引的统计信息出问题了,用exec dbms_stats.gather_index_stats收集了
下索引的统计信息,发现没有任何效果。我先加hints再来试一试,把第一行数据改为如下写法
select /*+index(creditlevelchange INDEX_CUSTOMERID)*/  count(0) from creditguarantee cg where 1=1
发现仍然不走索引,这就有点奇怪,这下应该是表的数据和索引有关系

jsjdata0
-- select max(CREATEDDATE) from creditguarantee 2012/2/23 17:46:01
-- select min(CREATEDDATE) from creditguarantee 2012/2/23 10:32:58

huifu2
-- select Max(CREATEDDATE) from creditguarantee  2012/2/3  16:48:56
-- select Min(CREATEDDATE) from creditguarantee  2012/1/20 14:45:52

这下原因就很简单了,它大于的时间在表里面根本就找不到

第一种情况:
select count(0) from creditguarantee cg where 1=1

           and cg.createddate>=to_date('2012-02-23 09:33:00','yyyy-MM-dd hh24:mi:ss')
           and cg.createddate<=to_date('2012-02-26 10:33:00','yyyy-MM-dd hh24:mi:ss')
           and 2=

再写细点,这种就不行


第二种情况:
下面这种就可以 
select count(0) from creditguarantee cg where 1=1

           and cg.createddate>=to_date('2012-02-23 10:40:00','yyyy-MM-dd hh24:mi:ss')
           and cg.createddate<=to_date('2012-02-26 10:33:00','yyyy-MM-dd hh24:mi:ss')
           and 2=

表里面数据时间长度的区间
   
     |-------------------------------------|
     2012/2/23 10:32:58                    2012/2/23 10:32:58


第一种情况:
|---------------------------------------------------------|
2012-02-23 09:33:00                                       2012-02-26 10:33:00


第二种情况:
               |------------------------------------------|
                2012-02-23 10:40:00                       2012-02-26 10:33:00  


总结:where后面的起始时间要大于表里面数据的时间,如果起始时间小于表里面的数据之后
,那个点上根本就没有数据,那就谈不上使用那个点上数据的索引了,所以强制走hints也补
会有效果。
在整个sql优化过程中,我一直把注意and 2= .....这语句的前面,通过执行计划我发现了他们
属于非相关联合型操作。所以找到问题点在上面之后就不需要关注下面的SQL了

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10678398/viewspace-717236/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10678398/viewspace-717236/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值