我有一個表,其中我跟蹤事件及其發生日期。 在某些情況下,事件發生的日期爲空(甚至是尚未發生,但已註冊)日期,空值和索引
快速統計:所有事件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