Параметры и повторное использование планов выполнения
Использование параметров, включая маркеры параметров в приложениях ADO, OLE DB и ODBC, может повысить уровень использования планов выполнения.
Примечание по безопасности |
---|
Использование параметров и маркеров параметров для хранения введенных конечными пользователями значений является более безопасным, чем сцепление значений в строку, которая затем выполняется методом API доступа к данным, инструкцией EXECUTE либо хранимой процедурой sp_executesql. |
Единственная разница между следующими двумя инструкциями SELECT — в значениях, сравниваемых в предложении WHERE:
SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = 1;
SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = 4;
Единственная разница между планами выполнения для данных запросов — в значении, хранимом для сравнения со столбцом ProductSubcategoryID. В то время как выявление факта формирования инструкциями одного и того же плана и повторного его использования является основной задачей SQL Server, SQL Server не всегда может это обнаружить в сложных инструкциях SQL.
Отделение констант от инструкции SQL с помощью параметров помогает реляционному механизму распознавать дубликаты планов. Параметры можно использовать следующими способами.
В языке Transact-SQL используйте процедуру sp_executesql:
DECLARE @MyIntParm INT SET @MyIntParm = 1 EXEC sp_executesql N'SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = @Parm', N'@Parm INT', @MyIntParm
Этот метод рекомендуется для сценариев языка Transact-SQL, хранимых процедур и триггеров, динамически формирующих инструкции SQL.
В технологиях ADO, OLE DB и ODBC используются маркеры параметров. Маркеры параметров представляют собой знаки вопроса (?), заменяющие константу в инструкции SQL и привязываемые к программной переменной. Например, в приложении ODBC можно сделать следующее:
использовать параметр SQLBindParameter для привязки целочисленной переменной к первому маркеру параметра в инструкции SQL;
поместить целочисленное значение в переменную;
выполнить инструкцию, указав маркер параметра (?):
SQLExecDirect(hstmt, "SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = ?", SQL_NTS);
Если в приложениях используются маркеры параметров, поставщик OLE DB для собственного клиента SQL Server и драйвер ODBC для собственного клиента SQL Server, включенные в состав SQL Server, используют для отправки инструкций в SQL Server процедуру sp_executesql.
Чтобы проектировать хранимые процедуры, использующие указанные разработчиком параметры.
Если структура приложения не предусматривает явной подготовки параметров, можно воспользоваться оптимизатором запросов SQL Server для автоматической параметризации некоторых запросов с использованием установленного по умолчанию поведения Простая параметризация. В качестве альтернативы можно заставить оптимизатор запросов учитывать параметризацию всех запросов к базе данных путем установки параметра PARAMETERIZATION инструкции ALTER DATABASE в значение FORCED. Дополнительные сведения см. в разделе Принудительная параметризация.
При включенной принудительной параметризации может также иметь место и простая параметризация. Например, в соответствии с правилами принудительной параметризации, следующий запрос не может быть параметризован:
SELECT * FROM Person.Address
WHERE AddressID = 1 + 2;
Однако он может быть параметризован согласно правилам простой параметризации. В случае неуспешной попытки принудительной параметризации впоследствии производятся попытки использования простой параметризации.
См. также