Статический против динамического SQL - PullRequest
5 голосов
/ 24 августа 2010

В моей базе данных в нескольких местах разработчики использовали динамический SQL вместо статического.И они говорят, что причина этого заключается в улучшении производительности.Может кто-нибудь сказать мне, может ли динамический sql действительно увеличить производительность в хранимой процедуре или блоке plsql?

Что будет выполняться быстрее и почему?
1.

begin  
    execute immediate 'delete from X';  
end;

2.

begin  
    delete from X;  
end;

Ответы [ 2 ]

13 голосов
/ 24 августа 2010

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

Основная причина использования динамического SQL для повышения производительности заключается в том, что оператор SQL может значительно различаться - т. Е. Вы можете добавить дополнительный код к предложению WHERE во время выполнения в зависимости от состояния системы (ограничить подзапрос по адресу, если адрес введен и т. д.).

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

Например, если у вас есть что-то вроде поля состояния, в котором данные распределяются неравномерно (но индексируются).

Рассмотрим следующие 3 утверждения, когда 95% данных обработано 'P'

   SELECT col FROM table 
   WHERE status = 'U'-- unprocessed
   AND company = :company

   SELECT col FROM table 
   WHERE status = 'P' -- processed
   AND company = :company

   SELECT col FROM table
   WHERE status = :status
   AND company = :company

В окончательной версии Oracle выберет общий план объяснения. В первой версии он может решить, что лучший план - начать с индекса статуса (зная, что необработанные записи составляют очень небольшую часть от общего числа).

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

Downsides

При каждом повторении одного и того же динамического оператора SQL выполняется мягкий анализ, который является небольшим дополнительным расходом по сравнению со статическим оператором, но по-прежнему является дополнительным.

Каждый новый SQL-оператор (динамический или статический) также блокирует SGA (разделяемую память) и может привести к выталкиванию «старых» операторов.

Плохой, но распространенный системный дизайн для кого-то, чтобы использовать динамический SQL для генерации простых выборок, которые меняются только по ключу - т.е.

SELECT col FROM table WHERE id = 5
SELECT col FROM table WHERE id = 20
SELECT col FROM table WHERE id = 7

Отдельные операторы будут быстрыми, но общая производительность системы ухудшится, так как это убивает общие ресурсы.

Также - гораздо сложнее отлавливать ошибки во время компиляции с помощью динамического SQL. При использовании PL / SQL это приводит к потере правильной проверки времени компиляции. Даже при использовании чего-то вроде JDBC (где вы перемещаете весь код вашей базы данных в строки - хорошая идея!) Вы можете получить предварительные парсеры для проверки содержимого JDBC. Динамический SQL = только тестирование во время выполнения.

Накладные

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

0 голосов
/ 24 августа 2010

К сожалению, это зависит от конкретного случая.

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

Ссылка, которую @DumbCoder дал в комментариях, имеет несколько отличных правил, которые также применимы к Oracle в большинстве случаев.Вы можете использовать что-то вроде этого, чтобы помочь вам принять решение, но не существует простого правила, такого как «динамический быстрее, чем статический».

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