Детерминированная функция SQL, которая может использовать объявление SYSDATE, все еще индексируется? - PullRequest
0 голосов
/ 22 октября 2018

Рассмотрим этот пример:

CREATE FUNCTION get_age(date_of_birth DATE) 
RETURN NUMBER AS
BEGIN
  RETURN 
    TRUNC(MONTHS_BETWEEN(SYSDATE, date_of_birth)/12);
END

Следующий запрос не может быть проиндексирован, поскольку get_age() не является детерминированным.

SELECT first_name, last_name, get_age(date_of_birth)
  FROM employees
  WHERE get_age(date_of_birth) = 42

Как вы по-прежнему можете использовать индекс для оптимизации запроса для всех 42-летних сотрудников?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Поместите индекс на date_of_birth и привыкните к написанию SQL как:

where date_of_birth > trunc(sysdate) - interval '43' year and
      date_of_birth <= trunc(sysdate) - interval '42' year

Это может использовать индекс на date_of_birth - плюс он точен для дня.

Или для високосного года:

where date_of_birth > add_months(trunc(sysdate), -43 * 12) and
      date_of_birth <= add_months(trunc(sysdate), -42*12)
0 голосов
/ 22 октября 2018

Вы можете просто добавить ключевое слово DETERMINISTIC в вашу функцию, тогда оно будет работать из синтаксиса.

Однако ваш индекс будет работать (то есть обеспечивает правильный результат) только на сегодняшний день!Если завтра человеку исполнится 43 года, то на следующей неделе ваш запрос все равно вернет ему 42 года.

В качестве некрасивого обходного пути вам придется перестраивать индекс каждый день.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...