как именно это работает
sf_get_local()
- это функция в вашем приложении, а не встроенная в Oracle, поэтому вы можете посмотреть на ее источник, чтобы выяснить, что он делает, а мы нет. Тем не менее, я предполагаю, что это преобразование временной метки в UTC в местный часовой пояс. trunc()
удаляет элемент времени, поэтому 2018-05-08 15:20:01.542
станет просто 2018-05-08
, что кажется немного странным, если операнды выражены в форматах даты и времени с точностью до секунды.
Что касается того, почему "SQL занимает часы", нам трудно сказать. Производительность диагностики требует гораздо больше подробностей. План объяснения поможет. Узнайте больше.
Очевидные вещи, на которые нужно посмотреть:
Предложение WHERE
, вероятно, не использует индекс (если только у вас нет индекса на основе функций в pipeline(trunc(sf_get_local(pipeline_tx_status_date,status_date_tz_code))
. Проблема в том, что вы фильтруете по диапазону дат, так что это трудно для Оптимизатор, который сообщает об использовании индекса, - это хорошо. Если диапазон составляет час, а вы сканируете данные за пять лет, то индекс полезен. Но не в том случае, если диапазон охватывает год, а у вас есть пять лет. данные.
Вы просматриваете час данных, поэтому, возможно, вы получите некоторую выгоду от построения индекса, основанного на функциях. Узнать больше .
Это соединение на самом деле является CROSS JOIN :
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
Вы не присоединяете pipeline_parties
по идентификатору к любой из других таблиц в запросе. Это означает, что ваш результирующий набор будет произведением всех остальных строк, каждая строка в pipeline_parties
, где partner_role = 'BT'
. Может быть, это всего лишь одна строка, и в этом случае вы должны четко указать CROSS JOIN. В противном случае возврат большего количества данных, чем вам нужно, вероятно, будет еще одной причиной, по которой запрос занимает время.
Некоторые из ваших объединений выглядят так :
JOIN multisegment_status ms ON phwb.pipeline_tx_id = ms.pipeline_tx_id
Но все идет от pipeline
. Вы можете помочь оптимизатору принять более разумное решение, соединив все дочерние таблицы с этой таблицей:
JOIN multisegment_status ms ON pinv.pipeline_tx_id = ms.pipeline_tx_id
Обратите внимание, что вы снова создаете продукт здесь. Если все эти другие таблицы не имеют отношения один к одному с pipeline
, вы будете генерировать перестановки всех выбранных записей. Вероятно, это не то, что вы хотите.
На данный момент мы должны указать, что это ваша модель данных и ваши бизнес-правила. Вы должны понимать логику, которую вы реализуете, и то, как данные соответствуют этой логике. Это означает, что вам необходимо понять взаимосвязь между таблицами в вашей модели данных.