Поделиться через


Подготовленное выполнение

API-интерфейс ODBC определяет подготовленное выполнение как способ уменьшить расходы на синтаксический анализ и компиляцию, связанные с повторным выполнением инструкции Transact-SQL. Приложение строит строку символов, содержащую инструкцию SQL, а затем выполняет ее в два этапа. Однократно вызывает функцию SQLPrepare, чтобы выполнить синтаксический анализ и компиляцию инструкции компонентом Компонент Database Engine в план выполнения. Затем вызывает функцию SQLExecute для каждого выполнения подготовленного плана выполнения. Это снижает расход ресурсов на синтаксический анализ и компиляцию при каждом выполнении. Подготовленное выполнение часто используется приложениями для многократного выполнения параметризованных инструкций SQL.

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

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

SQL Server также обеспечивает собственную поддержку подготовленного выполнения. План выполнения включает функцию SQLPrepare и все функции, выполняемые позже, и строится при вызове функции SQLExecute. Так как в SQL Server строить временные хранимые процедуры, основанные на функции SQLPrepare, не требуется, не возникает и дополнительных издержек в системных таблицах базы данных tempdb.

Из соображений производительности подготовка инструкции откладывается до вызова функции SQLExecute или до выполнения операции над метасвойством (такой, как SQLDescribeCol или SQLDescribeParam в ODBC). Это поведение по умолчанию. Любые ошибки в подготавливаемой инструкции неизвестны до выполнения инструкции или до выполнения операции над метасвойством. Установив атрибут инструкции SQL_SOPT_SS_DEFER_PREPARE в специфичное для ODBC-драйвера собственного клиента SQL Server значение SQL_DP_OFF, можно отключить это поведение по умолчанию.

В случае отложенной подготовки вызов либо функции SQLDescribeCol, либо функции SQLDescribeParam перед вызовом функции SQLExecute создает дополнительное обращение к серверу. При выполнении функции SQLDescribeCol драйвер удаляет предложение WHERE из запроса и отправляет его на сервер с инструкцией SET FMTONLY ON для получения описания столбцов первого результирующего набора, возвращаемого запросом. При выполнении функции SQLDescribeParam драйвер обращается к серверу для получения описания выражений или столбцов, на которые ссылается любой маркер параметра в запросе. Этот метод также имеет несколько ограничений, таких как невозможность обработки параметров вложенных запросов.

Злоупотребление функцией SQLPrepare с драйвером ODBC для собственного клиента SQL Server снижает производительность, особенно при соединении с предыдущими версиями SQL Server. Не следует использовать подготовленное выполнение для инструкций, исполняемых один раз. Подготовленное выполнение медленнее, чем прямое выполнение, для однократного выполнения инструкции, потому что оно требует дополнительного обращения клиента к серверу. В предыдущих версиях SQL Server оно также создает временную хранимую процедуру.

В SQL Server подготовленные инструкции нельзя применять для создания временных объектов.

Некоторые ранние ODBC-приложения использовали функцию SQLPrepare каждый раз при использовании функции SQLBindParameter. Функция SQLBindParameter не требует использования функции SQLPrepare, ее можно использовать с функцией SQLExecDirect. Например, используйте функцию SQLExecDirect с функцией SQLBindParameter для получения кода возврата или выходных параметров хранимой процедуры, которая выполняется только один раз. Не используйте функцию SQLPrepare с функцией SQLBindParameter, если одна и та же инструкция не будет выполняться несколько раз.

См. также

Основные понятия

Выполнение инструкций (ODBC)