Можете ли вы переписать функцию NVL? - PullRequest
1 голос
/ 28 апреля 2020

Я использую функцию NVL в своем предложении WHERE следующим образом.

... AND NVL(FIRST_DATE, SECOND_DATE) BETWEEN (SYSDATE - 7) and SYSDATE 

Что я делаю так: если FIRST_DATE равен нулю, тогда используйте SECOND_DATE для сравнения. Проблема в том, что он предотвращает использование индекса для столбца first_date или second_date. Поэтому я переписал условие в следующее:

... AND 
((FIRST_DATE BETWEEN (SYSDATE-7)  AND SYSDATE) 
OR 
(FIRST_DATE IS NULL AND SECOND_DATE BETWEEN (SYSDATE-7) AND SYSDATE))

Я протестировал его, запустив его с разными датами, и он всегда возвращал те же результаты, что и с функцией NVL. Но я хочу убедиться и проверить, не пропустил ли я никаких исключений, где результат может отличаться. Кто-нибудь может подтвердить, что то, что я сделал, семантически эквивалентно функции NVL?

1 Ответ

1 голос
/ 28 апреля 2020

Проблема на самом деле не NVL() сама по себе . Это просто усложнение предложения WHERE. Oracle поддерживает индексы для выражений, поэтому я бы порекомендовал новый индекс:

create index idx_t_dates on t(coalesce(first_date, second_date))

Затем, если вы используете то же выражение в предложении where, тогда следует использовать индекс:

and coalesce(first_date, second_date) between sysdate - 7 and sysdate

Я предпочитаю coalesce(), чем nvl(), потому что это стандартная функция с той же функциональностью.

...