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/