日期,空值和索引

时间:2016-06-16 09:01:23

标签: sql oracle performance

我有一张桌子,我跟踪事件及其发生的日期。 在某些情况下,事件发生日期为空(即使尚未发生,但已经注册)

快速统计:所有事件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 。也许这将有助于分析 执行计划是: execution plan

1 个答案:

答案 0 :(得分:1)

首先在构建索引之后 - 你分析了索引吗?

假设您有 - 您没有提到您正在运行的查询类型。 如果查询参数正在搜索NULL - 我不会对优化器选择在索引范围扫描上使用全表扫描感到惊讶。 毕竟,你的大多数记录集都有一个NULL日期值。

您还可以使用提示强制使用索引 即。 / * + index(events_table_idx)* /

但您需要仔细查看效果统计信息,以确定哪种方式是检索数据的最有效方法。