我有一个表,其中我跟踪事件及其发生日期。 在某些情况下,事件发生的日期为空(甚至是尚未发生,但已注册)日期,空值和索引
快速统计:所有事件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。也许这将有助于分析 执行计划: 所有的
为什么不使用默认值(例如2033-01-01,您使用NVL动态填充)设置空日期值?这似乎是解决大部分问题的好方法。 –
另一种解决方案可以将查询拆分为两部分 - 其中一个日期为空的部分,其自然会较慢(因为没有明显的过滤器并且它是大部分数据 - 因此索引不是选项),而另一个日期不为空,它将使用索引来查询日期特定的事件。 –
不幸的是我不能影响表格填充的方式,所以我必须照原样工作。关于分成两行的 ,我只能使用一个sql查询,而我提供的上一部分是我在较大选择中使用的JOIN之一。所以这也无济于事。感谢您的建议 – user2858200