2017-02-21 14 views
0

У меня есть большой стол Oracle с индексированной дата_время поле: «DISCONNECT_DATE»Как использовать Oracle индексированного поля в запросе

Когда я использую следующую команду, где пункт мой запрос выполняется быстро:

DISCONNECT_DATE > TO_DATE('01-DEC-2016', 'DD-MON-YYYY') AND 
DISCONNECT_DATE < TO_DATE('01-JAN-2017', 'DD-MON-YYYY') 

Когда я использую следующий пункт, где мой запрос работает (очень) медленно:

extract(month from disconnect_date) = '12' and 
extract(year from disconnect_date) = '2016' 

Они являются более или менее эквивалентны в своих намерениях. Почему первые работают, а позже нет? (Я не думаю, что эта проблема в SQL SERVER)

(я использую PL SQL Developer, чтобы написать запрос)

+0

Я полагаю, что Oracle не может автоматически преобразовать ваш второй вариант в первый вариант, поэтому он полностью сканирует. Для этой оптимизации понадобится специальный случай. PS. Они не эквивалентны, если вы не измените> на> = –

+0

Я смущен. Вы говорите, что в SQL Server обе версии работают очень быстро? Я ничего не знаю о SQL Server, но я бы нашел это очень удивительным. (Если у вас уже есть функциональные индексы в SQL Server, как показывает Гордон в его ответе.) – mathguy

ответ

4

Вопрос является использование индексов. В первом случае все функции находятся на «постоянной» стороне, а не на стороне «столбца». Таким образом, Oracle может легко видеть, что индекс может быть применен.

Логика, которая делает индексирование, однако, не понимает extract(), поэтому индекс не используется. Если вы хотите использовать эту конструкцию, вы можете создать индекс на вызовах функции:

create index idx_t_ddyear_ddmonth on t(extract(month from disconnect_date), extract(year from disconnect_date)); 

Примечания: extract() возвращает число не строку, так что вы должны избавиться от одинарных кавычек. Смешивание типов данных может также путать оптимизатор.

+0

Что вы подразумеваете под «постоянной» стороной или «столбец». Есть ли у вас пример, когда на одной стороне или другой из равных есть разница с Oracle? Я всегда считал, что это не имеет никакого значения. –

+0

@WW - не стороны, как в левом и правом; вы можете поменять термины так, чтобы ссылка «столбец» находилась справа от оператора (смена оператора тоже, чтобы при необходимости поддерживать логику). Это относится к данным, поступающим из столбца, напрямую или с помощью манипуляции (например, вызов функции, который является проблемой здесь), сравнивается с выражением, отличным от столбца. Какая бы сторона ни была. [Read more] (https://docs.oracle.com/database/121/SQLRF/sql_elements002.htm#SQLRF00214), отмечая вторую маркерную точку и раздел о правилах, регулирующих неявные преобразования типов данных :. –

+0

@WW - Пожалуйста, обратите пристальное внимание на то, что сказал Гордон в последнем абзаце (о правильном сопоставлении типов данных ваших выражений). Он на 100% прав - я готов сделать ставку на большую эффективность (в глобальном масштабе по всем запросам, которые выполняются во всех базах данных в мире) из-за халатности в отношении типов данных, чем из-за использования функций вокруг значений столбцов (например, 'extract() 'в вашем примере). Бонус ++ в Гордон за то, что потратил время, чтобы сделать это! – mathguy