我有一个表M,该表具有CREATED_AT和MODIFIED_AT列(日期),并且此表非常大。 我需要在过去5天内修改或创建行:
Select * from M where MODIFIED_AT >= trunc(sysdate)-5 OR CREATED_AT >= trunc(sysdate)-5
没有针对它们的索引,而且恐怕Oracle会进行完全扫描,而且速度会很慢。可以创建什么样的索引来改进它?
MODIFIED_AT为空,CREATED_AT为非空。 最好创建一个包含两个列的索引,还是分别为每个列创建2个索引?
更新 还有一件事:有人建议创建基于函数的索引合并(modified_at,created_at),问题是该表中的项目很少被修改,但通常以大块创建(由系统创建,如果需要则进行修改)用户)。因此,可能有很多具有相同created_at和nullmodified_at的项目。但仍然会有一些modified_at不为null的项目。创建位图索引有意义吗?还是任何其他使用这个事实的方法,对于表M中的大块项目,created_at将是相同的?
而且,将索引设为ASC还是DESC有什么区别吗?
答案 0 :(得分:2)
我建议使用union all
:
select m.*
from m
where CREATED_AT >= trunc(sysdate) - 5
union all
select m.*
from m
where MODIFIED_AT >= trunc(sysdate) - 5 and CREATED_AT < trunc(sysdate) - 5;
这可以利用m(created_at)
和m(modified_at, created_at)
上的索引。
一种简单的方法可能是确保在创建记录时设置modified_at
。然后,您可以这样做:
select m.*
from m
where MODIFIED_AT >= trunc(sysdate) - 5 ;
或者另一种选择是:
select m.*
from m
where greatest(MODIFIED_AT, created_at) >= trunc(sysdate) - 5 ;
,在m( greatest(MODIFIED_AT, created_at) )
上具有基于函数的索引。假设两个列都不是NULL
。