我有一张桌子,我跟踪事件及其发生的日期。 在某些情况下,事件发生日期为空(即使尚未发生,但已经注册)
快速统计:所有事件390k行,其中252k具有空日期
所以我在根据用户的请求提取数据时遇到问题: 1.用户可能想要拉尚未发生的事件; (用户输入*) 2.用户可以提取超过特定日期的事件; 3.用户可以提取超出特定日期的事件+尚未发生的事件;
我正在构建动态sql查询,类似于
select
even_id,
event_registered_date,
event_name,
event_occurred_date
from
events_table
where
NVL(event_occurred_date, to_date('2033-01-01','yyyy-mm-dd')) >= coalesce(to_date(replace(:p1, '*', NULL),'yyyy-mm-dd'),event_occurred_date,to_date('2033-01-01','yyyy-mm-dd'))
...--other filter conditions are here
这个sql中最耗费成本的部分是日期过滤器。我尝试创建基于函数的索引trunc(event_occurred_date)
,甚至包括空值trunc(NVL(event_occurred_date,to_date('2033-01-01','yyyy-mm-dd')))
,它仍然使用全表扫描。
我相信有更精巧的解决方法,但我只是看不到它。 提前致谢
加了: 我刚与桌面所有者交谈过,他们告诉我,在任何给定时间,至少有一半的事件会为 event_occurred_date 提供 nulls 。也许这将有助于分析 执行计划是:
答案 0 :(得分:1)
首先在构建索引之后 - 你分析了索引吗?
假设您有 - 您没有提到您正在运行的查询类型。 如果查询参数正在搜索NULL - 我不会对优化器选择在索引范围扫描上使用全表扫描感到惊讶。 毕竟,你的大多数记录集都有一个NULL日期值。
您还可以使用提示强制使用索引 即。 / * + index(events_table_idx)* /
但您需要仔细查看效果统计信息,以确定哪种方式是检索数据的最有效方法。