Описаны ли аналитические функции Oracle?

Кто-нибудь сталкивался с медленной производительностью при использовании аналитических функций оракула? Аналитическая функция lead() oracle использовалась для создания нового поля в таблице. В принципе, это позволит использовать значение предыдущего значения строки в качестве значения нового поля новой строки. План объяснения показывает, что полное сканирование таблицы выполняется в таблице, на которой использовалась аналитическая функция оракула.

Чтобы избежать затрат на это полное сканирование таблицы, мне может потребоваться просто вручную заполнить конкретное поле с предыдущим значением строки, используя триггер после вставки/обновления

Кто-нибудь решил не использовать аналитическую функцию оракула из-за его высокой стоимости? Следует ли редко использовать аналитические функции оракула?

Ответ 1

аналитические функции не обошлись без затрат: они должны хранить данные для промежуточных результатов (текущие итоги, функции окон...), которые нуждаются в памяти, и они также требуют некоторой вычислительной мощности. Некоторым функциям необходимо будет перейти к последней строке набора результатов, чтобы иметь возможность возвращать результат (например, MIN/MAX). Большинство функций также будут иметь неявную операцию SORT.

Таким образом, они не являются бесплатными с точки зрения ресурсов, но они являются операциями SET, и в большинстве случаев они намного эффективнее, чем запись пользовательской строковой процедуры plsql или традиционного SQL.

Вам придется сравнивать и сравнивать в своем конкретном случае, но если вы будете использовать их с умом, вы увидите, что они являются мощным инструментом производительности, а не помехой.

Ответ 2

Некоторые подробности об этом доступны в блоге Джонатана Льюиса здесь.

Действительно, вопрос должен быть, являются ли они более или менее дорогостоящими, чем альтернатива, и это придет к конкретной ситуации. В некоторых случаях вы, возможно, предпочитаете извлекать данные на сервер приложений и обрабатывать их там только потому, что на этом уровне обычно дешевле/проще иметь дополнительное оборудование.

Но, учитывая выбор между выполнением этого в SQL и добавлением PL/SQL-обработки, я обычно использовал SQL.

Ответ 3

Это зависит от того, как индексируется ваша таблица и какие функции вы используете.

ROW_NUMBER(), например, представляется менее эффективным, чем ROWNUM, даже если используются индексы. См. Эту статью в своем блоге для сравнения производительности:

Оптимизатор

Oracle знает о функциях окна и может использовать несколько трюков, таких как STOPKEY и PUSHED RANK, которые делают их более эффективными.

План объяснения показывает, что полное сканирование таблицы выполняется в таблице, на которой была использована аналитическая функция оракула. ​​

Сканирование таблицы не плохо. Это может быть действительно оптимальным, если TABLE ACCESS для получения значений, отсутствующих в индексе, дороже, чем фильтрация и сортировка.

Обычно, если ваша таблица индексирована, предложения WHERE и ORDER BY позволяют использовать этот индекс для упорядочения, и оптимизатор считает, что этот индекс стоит использовать, метод WINDOW BUFFER используется для LAG и LEAD функции.

Двигатель просто сохраняет бегущий буфер из 2 строк (или больше, в зависимости от значения смещения) и возвращает значения из первой и второй строк.

Однако оптимизатор может считать, что индекс не стоит использовать вообще.

В этом случае он будет использовать WINDOW SORT: то же самое, но сортировка выполняется в памяти или в временном табличном пространстве.

Ответ 4

Конечно, у них есть стоимость, и вам нужно решить, сможете ли вы это заплатить или нет.

В моем случае я создал хранимую процедуру, которая выполняет итерацию таблицы и вычисляет некоторые даты с помощью функции Oracle lead() и сохраняет результаты в другой таблице. Наконец, я использую эту более позднюю таблицу в своем приложении и обновляю первую таблицу (запустив хранимую процедуру) один раз в неделю, потому что эти данные не часто меняются.

Для меня это было лучшим решением.