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


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

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

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

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

Среда SQL Server 2000 и более поздние версии обеспечивают собственную поддержку подготовленного выполнения. План выполнения строится на функции SQLPrepare и выполненных позже, когда вызвана функция SQLExecute. Так как SQL Server 2000 и более поздние версии не требуют строить временные хранимые процедуры на функции 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 2000 и более поздних версиях, и в предыдущих версиях SQL Server, если параметр создания хранимых процедур активен. При включенном данном параметре, подготовленная инструкция строится внутри хранимой процедуры, которая выполняется при вызове SQLExecute. Любой временный объект, созданный в процессе выполнения хранимой процедуры, автоматически удаляется, когда процедура заканчивается. Результатом, полученным в следующих примерах, является временная таблица #sometable, которая не будет создана, если активен параметр создания хранимых процедур для подготовки.

SQLPrepare(hstmt,   "CREATE TABLE #sometable(cola int, colb char(8))",   SQL_NTS);SQLExecute(hstmt);

или

SQLPrepare(hstmt,   "SELECT * FROM Authors INTO #sometable",   SQL_NTS);SQLExecute(hstmt);

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

См. также

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