ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SQL优化--强制走索引失效的情况

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

原创 Linux操作系统 作者:wadekobe9 时间:2012-02-27 17:06:48 0 删除 编辑
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/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 转载--oracle DML锁
下一篇: 转载--事务隔离
请登录后发表评论 登录
全部评论

注册时间:2010-11-30

  • 博文量
    36
  • 访问量
    56491