有个performance的问题想请问大家,请先看下面这个示意的select语句
select count(*)
from A, B, C
where A.field1 = C.field1
and A.field2 = B.field2
and A.date >= to_date('2005-01-01', 'yyyy-mm-dd')
and A.date < to_date('2006-01-01', 'yyyy-mm-dd');表A是个大表,大概有300万条记录。表B和C都是小表。表A在字段date上建有索引。
整个语句执行的时候大概是200秒,如果去除最后两个and条件,可以达到20多秒这样的十位数量级的速度,如果把最后两个and条件变成'A.date = to_date('2005-01-01', 'yyyy-mm-dd')’,速度会更快。
但是需求就是要求在一个时间范围类搜索记录。
我的问题有两个:
[1] 'and A.date >= to_date('2005-01-01', 'yyyy-mm-dd') and A.date < to_date('2006-01-01', 'yyyy-mm-dd')' 这两个条件中是否会使用索引?因为我听说如果在索引字段上使用函数,就不会走索引。
[2] 如何提高示意语句的performance,能够提高到100秒也是好的。
先谢谢大家的踊跃发言:)。
select count(*)
from A, B, C
where A.field1 = C.field1
and A.field2 = B.field2
and A.date >= to_date('2005-01-01', 'yyyy-mm-dd')
and A.date < to_date('2006-01-01', 'yyyy-mm-dd');表A是个大表,大概有300万条记录。表B和C都是小表。表A在字段date上建有索引。
整个语句执行的时候大概是200秒,如果去除最后两个and条件,可以达到20多秒这样的十位数量级的速度,如果把最后两个and条件变成'A.date = to_date('2005-01-01', 'yyyy-mm-dd')’,速度会更快。
但是需求就是要求在一个时间范围类搜索记录。
我的问题有两个:
[1] 'and A.date >= to_date('2005-01-01', 'yyyy-mm-dd') and A.date < to_date('2006-01-01', 'yyyy-mm-dd')' 这两个条件中是否会使用索引?因为我听说如果在索引字段上使用函数,就不会走索引。
[2] 如何提高示意语句的performance,能够提高到100秒也是好的。
先谢谢大家的踊跃发言:)。
to_char(A.date,'yyyy-mm-dd') 对字段用函数就用不到了[2]不知道
如果时间段很短,出来的数据远小于300万,可以先select a
select * from A where date >= to_date('2005-01-01', 'yyyy-mm-dd')
and date < to_date('2006-01-01', 'yyyy-mm-dd');
再做运算
对于第二个问题,
select * from A
where date >= to_date('2005-01-01', 'yyyy-mm-dd')
and date < to_date('2006-01-01', 'yyyy-mm-dd');
选出来的数据量也不小,如果是一年的范围,一般是60多万条记录。我希望的是能够在一条select语句完成所有的运算。如果是先选出来再做运算,就得写成procedure,因为这个select语句其实是上层的C++界面程序调用完成的。
from A, B, C
where A.field1 = C.field1
and A.field2 = B.field2
and A.date >= to_date('2005-01-01', 'yyyy-mm-dd')
and A.date < to_date('2006-01-01', 'yyyy-mm-dd');
让索引失效看看,应该跟
select count(*)
from A, B, C
where A.field1 = C.field1
and A.field2 = B.field2;
性能差不多,你访问了表里面的1/5的数据,再用索引就不能其到加快速度的效果,反而起反作用了
A.date+0 >= to_date('2005-01-01', 'yyyy-mm-dd')
and A.date+0 < to_date('2006-01-01', 'yyyy-mm-dd'); 也可以使用索引失效。
select count(*)
from
(select * from
(select * from a,b where and A.field2 = B.field2 ) t1,
(select * from a,c where and A.field1 = C.field1 ) t2) t
where t.data between sysdate-天数1 and sysdate-天数2