Я написал скалярную функцию (DYNAMIC_DATE
), которая преобразует текстовое значение в дату/время. Например, DYANMIC_DATE('T-1')
(T-1 = сегодня минус 1 = «вчера») возвращает 08-AUG-2012 00:00:00
. Он также принимает строки даты: DYNAMIC_DATE('10/10/1974')
.Скалярная функция Oracle в выражении WHERE приводит к плохой работе
Функция использует операторы CASE
для анализа единственного параметра и расчета даты относительно sysdate
.
Хотя это не делает использование любой таблицы в своей схеме, он делает использование TABLE
типа для хранения строк даты формата:
TYPE VARCHAR_TABLE IS TABLE OF VARCHAR2(10);
formats VARCHAR_TABLE := VARCHAR_TABLE ('mm/dd/rrrr','mm-dd-rrrr','rrrr/mm/dd','rrrr-mm-dd');
Когда я использую функцию в предложении SELECT
, то запрос возвращает в < 1 секунду:
SELECT DYNAMIC_DATE('MB-1') START_DATE, DYNAMIC_DATE('ME-1') END_DATE
FROM DUAL
Если я использую его против нашей даты таблицы измерения (91311 всего записей), запрос завершается в < 1 второе:
SELECT count(1)
from date_dimension
where calendar_dt between DYNAMIC_DATE('MB-1') and DYNAMIC_DATE('ME-1')
Другие, однако, возникают проблемы с функцией, если она используется против большой таблицы (26,301,317 записи):
/*
cost: 148,840
records: 151,885
time: ~20 minutes
*/
SELECT count(1)
FROM ORDERS ord
WHERE trunc(ord.ordering_date) between DYNAMIC_DATE('mb-1') and DYNAMIC_DATE('me-1')
Однако, тот же запрос, используя «жестко закодированные» даты, возвращает довольно быстро: установка ванильного
/*
cost: 144,257
records: 151,885
time: 62 seconds
*/
SELECT count(1)
FROM ORDERS ord
WHERE trunc(ord.ordering_date) between to_date('01-JUL-2012','dd-mon-yyyy') AND to_date('31-JUL-2012','dd-mon-yyyy')
поставщика не включает в себя индекс на ORDERING_DATE
поля.
объяснить планы обоих запросов аналогичны:
с функцией:
с жестко закодированными датами:
- ли функция
DYNAMIC_DATE
вызывается несколько раз вWHERE
статья? - Что еще может объяснить несоответствие?
** редактировать **
NONUNIQUE
индекс был добавлен в таблицу Orders. Оба запроса выполняются в < 1 секунда. Оба плана одинаковы (подход), но тот, у кого функция, является более низкой стоимостью.
Я удалил из функции ключевое слово DETERMINISTIC
; запрос выполнен в < 1 секунда.
- Действительно ли проблема с функцией или она связана с таблицей?
- Через 3 года, когда эта таблица еще больше, и если я не включу ключевое слово
DETERMINISTIC
, будет ли запрос пострадать? - Будет ли ключевое слово
DETERMINISTIC
повлиять на результаты функции? Если завтра я запустилDYNAMIC_DATE('T-1')
, получаю ли я такие же результаты, как если бы я запускал его сегодня (08/09/2012)? Если это так, этот подход не будет работать.
Если планы объяснения схожи, значит ли это, что они не идентичны? Если они не идентичны, можете ли вы опубликовать два плана? –
Планы - это то же самое (что означает шаги); только общая стоимость отличается. – craig
Сколько записей в «ORDERS»? – Ollie