Указания запросов (Transact-SQL)
Подсказки в запросе указывают, что для запроса должна использоваться заданная подсказка. Они влияют на все операторы в инструкции. Если в основном запросе используется операция UNION, только последний запрос, использующий ее, может содержать предложение OPTION. Подсказки в запросе указываются как часть предложения OPTION. Если оптимизатор запросов не формирует допустимый план из-за одной или нескольких указаний в запросе, возникает ошибка 8622.
Внимание! |
---|
Поскольку оптимизатор запросов SQL Server обычно выбирает лучший план выполнения запроса, использовать подсказки рекомендуется только опытным разработчикам и администраторам баз данных в самом крайнем случае. |
Область применения:
Синтаксические обозначения Transact-SQL
Синтаксис
<query_hint > ::=
{ { HASH | ORDER } GROUP
| { CONCAT | HASH | MERGE } UNION
| { LOOP | MERGE | HASH } JOIN
| EXPAND VIEWS
| FAST number_rows
| FORCE ORDER
| IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX
| KEEP PLAN
| KEEPFIXED PLAN
| MAXDOP number_of_processors
| MAXRECURSION number
| OPTIMIZE FOR ( @variable_name { UNKNOWN | = literal_constant } [ , ...n ] )
| OPTIMIZE FOR UNKNOWN
| PARAMETERIZATION { SIMPLE | FORCED }
| RECOMPILE
| ROBUST PLAN
| USE PLAN N'xml_plan'
| TABLE HINT ( exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
}
<table_hint> ::=
[ NOEXPAND ] {
INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value )
| FORCESEEK [( index_value ( index_column_name [,... ] ) ) ]
| FORCESCAN
| HOLDLOCK
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| READUNCOMMITTED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| SPATIAL_WINDOW_MAX_CELLS = integer
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Аргументы
{ HASH |ORDER } GROUP
Указывает, что агрегаты, описываемые в предложениях GROUP BY или DISTINCT запроса, должны использовать хэширование или упорядочивание.{ MERGE |HASH |CONCAT } UNION
Указывает, что все операции UNION выполняются слиянием, хэшированием или объединением наборов UNION. Если задано несколько указаний UNION, оптимизатор запросов выбирает наименее затратную стратегию из указанных.{ LOOP | MERGE | HASH } JOIN
Указывает, что все операции соединения во всем запросе выполняются с помощью рекомендаций LOOP JOIN, MERGE JOIN или HASH JOIN. Если задано больше одного указания соединения, оптимизатор запросов выбирает наименее затратную стратегию из допустимых.Если в одном запросе указание соединения задано для определенной пары таблиц в предложении FROM, оно имеет приоритет в соединении двух таблиц, хотя также следует учитывать указания запросов. Таким образом, указание соединения для пары таблиц может только ограничивать выбор допустимых методов соединения для указания запроса. Дополнительные сведения см. в разделе Указания в соединении (Transact-SQL).
EXPAND VIEWS
Указывает, что выполняется разворачивание индексированных представлений и оптимизатор запросов не будет рассматривать индексированные представления как замену каким-либо частям запроса. Представление разворачивается при замене имени представления на определение представления в тексте запроса.Это указание запроса виртуально запрещает прямое использование индексированных представлений и индексов для индексированных представлений в плане запроса.
Индексированное представление не разворачивается только в том случае, если на представление существует прямая ссылка в части SELECT запроса и определены подсказки WITH (NOEXPAND) или WITH (NOEXPAND, INDEX( index_value [ ,...n ] ) ). Дополнительные сведения о подсказке в запросе WITH (NOEXPAND) см. в разделе FROM.
Действие этого указания распространяется только на представления в части SELECT инструкций, включая те, что находятся в инструкциях INSERT, UPDATE, MERGE и DELETE.
FAST number_rows
Указывает, что запрос оптимизирован для быстрого получения первых number_rows. строк. Оно должно быть неотрицательным целым числом. После возвращения первых number_rows строк запрос продолжает выполняться и возвращает полный результирующий набор.FORCE ORDER
Указывает, что при оптимизации запроса сохраняется порядок соединения, заданный синтаксисом запроса. Использование подсказки FORCE ORDER не влияет на возможный реверс ролей в оптимизаторе запросов.Примечание Инструкция MERGE получает доступ вначале к исходной таблице, затем к целевой в порядке соединения, принятом по умолчанию, если не задано предложение WHEN SOURCE NOT MATCHED. Если указать FORCE ORDER, сохраняется поведение по умолчанию.
KEEP PLAN
Заставляет оптимизатор запросов снизить приблизительный порог повторной компиляции для запроса. Предполагаемое пороговое значение повторной компиляции — это точка, в которой запрос автоматически перекомпилируется, если в таблице при выполнении инструкций UPDATE, DELETE или INSERT изменилось ожидаемое количество индексированных столбцов. Указывая подсказку KEEP PLAN, убедитесь, что запрос не будет часто перекомпилирован при выполнении множественных обновлений в таблице.KEEPFIXED PLAN
Принуждает оптимизатор запросов не перекомпилировать запрос при изменении статистики. Указывая подсказку KEEPFIXED PLAN, убедитесь, что запрос будет перекомпилирован только при изменении схемы базовых таблиц или если по отношению к ним выполнена процедура sp_recompile.IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX
Предотвращает использование в запросе некластеризованного индекса columnstore с оптимизацией для памяти xVelocity. Если в запросе содержится указание запроса, исключающее использование индекса columnstore, а также указание индекса для использования индекса columnstore, то данные указания будут конфликтовать между собой, и запрос вернет ошибку.MAXDOP number
Переопределяет параметр конфигурации max degree of parallelism хранимой процедуры sp_configure и регулятора ресурсов для запросов, в которых указывается этот параметр. Подсказка в запросе MAXDOP может превысить значение, заданное с помощью процедуры sp_configure. Если MAXDOP превышает значение, настроенное с помощью регулятора ресурсов, компонент Компонент Database Engine использует значение MAXDOP регулятора ресурсов, описанное в разделе ALTER WORKLOAD GROUP (Transact-SQL). Все семантические правила, используемые параметром конфигурации max degree of parallelism, применимы при использовании подсказки в запросе MAXDOP. Дополнительные сведения см. в разделе Настройка параметра конфигурации сервера max degree of parallelism.Внимание! Если значение MAXDOP равно нулю, то сервер выбирает максимальную степень параллелизма.
MAXRECURSION number
Указывает максимальное число рекурсий, допустимых для данного запроса. number представляет собой неотрицательное целое число между 0 и 32767. Если указано значение 0, ограничения не применяются. Если этот параметр не указан, ограничение по умолчанию равно 100.Если в процессе выполнения запроса достигнуто указанное число или число по умолчанию для подсказки MAXRECURSION, выполнение запроса завершается и возвращается ошибка.
Из-за этой ошибки все действия инструкции откатываются. Если это инструкция SELECT, может быть возвращена часть результатов или не возвращено ничего. Любые возвращенные частичные результаты могут не включать всех строк на рекурсивных уровнях, расположенных за указанным максимальным уровнем рекурсии.
Дополнительные сведения см. в разделе WITH обобщенное_табличное_выражение (Transact-SQL).
OPTIMIZE FOR ( @variable\_name { UNKNOWN | = literal_constant } [ , ...n ] )
Указывает оптимизатору, что при компиляции и оптимизации запросов нужно использовать конкретное значение для локальной переменной. Значение используется только в процессе оптимизации запроса, но не в процессе выполнения.@variable\_name
Имя локальной переменной, используемой в запросе, которой может быть присвоено значение для использования с указанием запроса OPTIMIZE FOR.UNKNOWN
Указывает, что оптимизатор запросов использует статистические данные вместо начального значения, чтобы определить значение локальной переменной при оптимизации запроса.literal_constant
Значение константы-литерала, присваиваемое @variable\_name для использования совместно с указанием запроса OPTIMIZE FOR. literal_constant используется только в процессе оптимизации запроса, но не используется как значение @variable\_name во время выполнения запроса. literal_constant может быть любым системным типом данных SQL Server, который может быть выражен как константа-литерал. Тип данных значения literal_constant должен неявно приводиться к типу данных, на который ссылается аргумент @variable\_name в запросе.
Подсказка OPTIMIZE FOR может использоваться для отмены определения параметров по умолчанию в оптимизаторе или при создании структуры плана. Дополнительные сведения см. в разделе Перекомпиляция хранимой процедуры.
OPTIMIZE FOR UNKNOWN
Если запрос скомпилирован и оптимизирован, предписывает оптимизатору запросов использовать статистические данные вместо начальных значений для всех локальных переменных, включая параметры, созданные с принудительной параметризацией.Если подсказки OPTIMIZE FOR @variable\_name = literal_constant и OPTIMIZE FOR UNKNOWN используются в одном указании запроса, оптимизатор запросов будет использовать аргумент literal_constant, указанный для конкретного значения, и UNKNOWN — для оставшихся значений переменных. Значения используются только в процессе оптимизации запроса, но не в процессе выполнения.
PARAMETERIZATION { SIMPLE | FORCED }
Указывает правила параметризации SQL Server, которые оптимизатор запросов применяет к запросу при его компиляции.Важно! Указание запроса PARAMETERIZATION может быть задано только внутри структуры плана. Она не может быть определена напрямую в запросе.
Значение SIMPLE дает оптимизатору запросов указание использовать простую параметризацию. Значение FORCED дает оптимизатору запросов рекомендацию использовать принудительную параметризацию. Указание запроса PARAMETERIZATION используется для переопределения текущих настроек параметра PARAMETERIZATION в структуре плана базы данных. Дополнительные сведения см. в разделе Указание механизма параметризации запросов с помощью структур плана.
RECOMPILE
Указывает компоненту Компонент SQL Server Database Engine отбросить план, сформированный после выполнения запроса, заставляя оптимизатор запросов перекомпилировать план запроса при следующем выполнении этого запроса. Без указания подсказки RECOMPILE компонент Компонент Database Engine кэширует планы запросов и использует их повторно. При компиляции планов запроса указание запроса RECOMPILE использует текущие значения всех локальных переменных в запросе и, если запрос находится внутри хранимой процедуры, текущие значения для всех параметров.Подсказка RECOMPILE — это полезная альтернатива созданию хранимых процедур, использующих предложение WITH RECOMPILE, в тех случаях, когда нужно перекомпилировать лишь часть запросов в хранимой процедуре, а не всю хранимую процедуру. Дополнительные сведения см. в разделе Перекомпиляция хранимой процедуры. Подсказка RECOMPILE также полезна для создания структур планов.
ROBUST PLAN
Заставляет оптимизатор запросов использовать план, который работает со строками наибольшего потенциального размера, возможно, с потерей производительности. При обработке запроса промежуточным таблицам и операторам может понадобиться сохранять и обрабатывать строки, которые шире, чем любые из входных строк. Строки могут быть настолько широки, что иногда некоторые операторы не смогут их обработать. Когда это происходит, компонент Компонент Database Engine возвращает ошибку при выполнении запроса. С помощью подсказки ROBUST PLAN оптимизатору запросов дается указание не выбирать ни один из планов запросов, который может вызвать проблему.Если такой план невозможен, оптимизатор запросов возвращает ошибку сразу, не откладывая обнаружение ошибок на момент выполнения запроса. Строки могут содержать столбцы переменной длины; компонент Компонент Database Engine позволяет указать для строк максимальный потенциальный размер, при превышении которого компонент Компонент Database Engine может не суметь обработать их. В основном, несмотря на максимальный потенциальный размер, приложение сохраняет строки, имеющие актуальные размеры с ограничениями, которые компонент Компонент Database Engine может обработать. Если компонент Компонент Database Engine встречает слишком длинную строку, возвращается ошибка выполнения.
USE PLAN N**'xml_plan'**
Принуждает оптимизатор запросов использовать существующий план запроса для запроса, определенного параметром «xml_plan». Подсказку USE PLAN нельзя указывать в инструкциях INSERT, UPDATE MERGE и DELETE.TABLE HINT (exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
Применяет заданную табличную подсказку к таблице или представлению, соответствующему аргументу exposed_object_name. Табличные подсказки рекомендуется использовать в качестве подсказок в запросах только в контексте структуры плана.Аргумент exposed_object_name может представлять одну из следующих ссылок.
Если в предложении FROM запроса используется псевдоним таблицы или представления, этим псевдонимом является exposed_object_name.
Если псевдоним не используется, exposed_object_name является точным соответствием таблицы или представления, на которые ссылается предложение FROM. Например, если в таблице или представлении имеется ссылка с двухкомпонентным именем, аргумент exposed_object_name представляет собой это двухкомпонентное имя.
Если аргумент exposed_object_name задан без указания табличной подсказки, все индексы, заданные в запросе как часть табличной подсказки, не учитываются, а использование индексов определяется оптимизатором запросов. Этот метод можно использовать для устранения влияния табличного указания INDEX, если невозможно изменить первоначальный запрос. См. пример К.
<table_hint> ::= { [ NOEXPAND ] { INDEX ( index_value [ ,...n ] ) | INDEX = ( index_value ) | FORCESEEK [(index_value(index_column_name [,... ] )) ]| FORCESCAN | HOLDLOCK | NOLOCK | NOWAIT | PAGLOCK | READCOMMITTED | READCOMMITTEDLOCK | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE |SPATIAL_WINDOW_MAX_CELLS | TABLOCK | TABLOCKX | UPDLOCK | XLOCK }
Табличная подсказка, применяемая в качестве подсказки в запросе к таблице или представлению, которое соответствует аргументу exposed_object_name . Описание этих подсказок см. в разделе Табличные указания (Transact-SQL).Табличные указания, за исключением INDEX, FORCESCAN и FORCESEEK, не могут использоваться как указания запроса, кроме тех случаев, когда в запросе уже содержится предложение WITH, задающее табличное указание. Дополнительные сведения см. в разделе «Примечания».
Внимание! Указание FORCESEEK с параметрами ограничивает число планов, которые могут быть использованы оптимизатором, в отличие от указания FORCESEEK без параметров. Из-за этого может чаще возникать ошибка «Невозможно сформировать план». В будущих выпусках внутренние изменения оптимизатора могут привести к увеличению числа этих планов.
Замечания
Указания запросов нельзя задавать в инструкции INSERT, кроме случая, когда внутри инструкции используется предложение SELECT.
Указания запросов можно задавать только в запросах верхнего уровня, но не во вложенных запросах. Если табличная подсказка задана в качестве подсказки в запросе, ее можно указать в запросе верхнего уровня или во вложенном запросе. Тем не менее, значение аргумента exposed_object_name в предложении TABLE HINT должно точно соответствовать видимому имени в запросе или вложенном запросе.
Определение табличных указаний как указаний запроса
Табличные указания INDEX, FORCESCAN или FORCESEEK рекомендуется использовать в качестве указаний запроса только в контексте руководства плана. Структуры планов полезны, если нельзя изменить первоначальный запрос, например потому, что он является приложением стороннего разработчика. Указания запроса, заданные в структуре планов, добавляются к запросу перед его компиляцией и оптимизацией. В автоматизированных запросах предложение TABLE HINT используется только при тестировании инструкций структуры планов. Для всех других нерегламентированных запросов рекомендуется задавать эти указания только как табличные.
Табличные указания INDEX, FORCESCAN и FORCESEEK, определенные в качестве указаний запроса, допустимы для следующих объектов:
Таблицы
Представления
Индексированные представления
Обобщенные табличные выражения (подсказку необходимо указывать в инструкции SELECT, результирующий набор которой заполняет обобщенное табличное выражение)
Динамические административные представления
Именованные вложенные запросы
Табличные указания INDEX, FORCESCAN и FORCESEEK могут быть заданы как указания запроса для запроса, у которого нет существующих табличных указаний. Кроме того, они могут использоваться для замены соответственно существующих указаний INDEX, FORCESCAN или FORCESEEK в таком запросе. Табличные указания, за исключением INDEX, FORCESCAN и FORCESEEK, не могут использоваться как указания запроса, кроме тех случаев, когда в запросе уже содержится предложение WITH, задающее табличное указание. В этом случае, чтобы сохранить семантику запроса, необходимо также задать соответствующее табличное указание в качестве указания запроса, задав в предложении OPTION ключевое слово TABLE HINT. Например, если запрос содержит табличное указание NOLOCK, то предложение OPTION в параметре @hints руководства плана также должно содержать указание NOLOCK. См. пример Л. При определении табличного указания, отличного от INDEX, FORCESCAN или FORCESEEK, с использованием TABLE HINT в предложении OPTION без совпадающего указания запроса (или наоборот), возникнет ошибка 8702 (указывающая, что предложение OPTION может вызвать изменение семантики запроса), а запрос завершится с ошибкой.
Примеры
А.Использование MERGE JOIN
В следующем примере указывается, что операция JOIN в запросе выполняется с подсказкой MERGE JOIN.
USE AdventureWorks2012;
GO
SELECT *
FROM Sales.Customer AS c
INNER JOIN Sales.vStoreWithAddresses AS sa
ON c.CustomerID = sa.BusinessEntityID
WHERE TerritoryID = 5
OPTION (MERGE JOIN);
GO
Б.Использование OPTIMIZE FOR
В следующем примере оптимизатору запросов предписывается использовать значение 'Seattle' для локальной переменной @city\_name и использовать статистические данные для определения локальной переменной @postal\_code при оптимизации запроса.
USE AdventureWorks2012;
GO
DECLARE @city_name nvarchar(30);
DECLARE @postal_code nvarchar(15);
SET @city_name = 'Ascheim';
SET @postal_code = 86171;
SELECT * FROM Person.Address
WHERE City = @city_name AND PostalCode = @postal_code
OPTION ( OPTIMIZE FOR (@city_name = 'Seattle', @postal_code UNKNOWN) );
GO
В.Использование MAXRECURSION
Подсказка MAXRECURSION может использоваться для предотвращения входа в бесконечный цикл из-за неверно сформированного рекурсивного обобщенного табличного выражения. В следующем примере специально создается бесконечный цикл и используется подсказка MAXRECURSION для ограничения количества уровней рекурсии до двух.
USE AdventureWorks2012;
GO
--Creates an infinite loop
WITH cte (CustomerID, PersonID, StoreID) AS
(
SELECT CustomerID, PersonID, StoreID
FROM Sales.Customer
WHERE PersonID IS NOT NULL
UNION ALL
SELECT cte.CustomerID, cte.PersonID, cte.StoreID
FROM cte
JOIN Sales.Customer AS e
ON cte.PersonID = e.CustomerID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT CustomerID, PersonID, StoreID
FROM cte
OPTION (MAXRECURSION 2);
GO
После исправления ошибки в коде подсказка MAXRECURSION больше не нужна.
Г.Использование MERGE UNION
В следующем примере используется указание запроса MERGE UNION.
USE AdventureWorks2012;
GO
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours
FROM HumanResources.Employee AS e1
UNION
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO
Д.Использование HASH GROUP и FAST
В следующем примере используется подсказка в запросе HASH GROUP и FAST.
USE AdventureWorks2012;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO
Е.Использование MAXDOP
В следующем примере используется подсказка в запросе MAXDOP.
USE AdventureWorks2012 ;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (MAXDOP 2);
GO
Ж.Использование INDEX
В следующем примере используется указание в запросе INDEX. В первом примере задан один индекс. Во втором примере указывается несколько индексов для одной табличной ссылки. В обоих примерах (поскольку указание INDEX применяется к таблице с псевдонимом) в предложении TABLE HINT необходимо задать псевдоним, совпадающий с именем видимого объекта.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE e.OrganizationLevel = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_OrganizationLevel_OrganizationNode)))';
GO
EXEC sp_create_plan_guide
@name = N'Guide2',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE e.OrganizationLevel = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_BusinessEntityID, IX_Employee_OrganizationLevel_OrganizationNode)))';
GO
З.Использование FORCESEEK
В следующем примере используется табличное указание FORCESEEK. Поскольку указание INDEX применяется к таблице с двухкомпонентным именем, в предложении TABLE HINT необходимо задать двухкомпонентное имя, совпадающее с именем видимого объекта.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide3',
@stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.JobTitle
FROM HumanResources.Employee
JOIN Person.Person AS c ON HumanResources.Employee.BusinessEntityID = c.BusinessEntityID
WHERE HumanResources.Employee.OrganizationLevel = 3
ORDER BY c.LastName, c.FirstName;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT( HumanResources.Employee, FORCESEEK))';
GO
И.Использование нескольких табличных указаний
В следующем примере к одной таблице применяется указание INDEX, а к другой — указание FORCESEEK.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide4',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE OrganizationLevel = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_OrganizationLevel_OrganizationNode ) )
, TABLE HINT ( c, FORCESEEK) )';
GO
К.Использование TABLE HINT для замещения существующего табличного указания
В следующем примере показан способ использования указания TABLE HINT без задания указания для переопределения поведения табличного указания INDEX, заданного в предложении FROM запроса.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide5',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_OrganizationLevel_OrganizationNode))
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE OrganizationLevel = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e))';
GO
Л.Определение табличных указаний, влияющих на семантику
В следующем примере запрос содержит два табличных указания: NOLOCK, которая изменяет семантику, и INDEX, которая не изменяет семантику. Чтобы сохранить семантику запроса, указание NOLOCK задается в предложении OPTIONS структуры плана. Помимо указания NOLOCK, задаются указания INDEX и FORCESEEK, которые замещают не изменяющее семантику указание INDEX в запросе, когда инструкция компилируется и оптимизируется.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide6',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE OrganizationLevel = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_OrganizationLevel_OrganizationNode) , NOLOCK, FORCESEEK ))';
GO
В следующем примере показан альтернативный метод сохранения семантики запроса, позволяющий оптимизатору выбрать другой индекс, в отличие от заданного в табличном указании. Это делается путем задания указания NOLOCK в предложении OPTIONS (поскольку оно изменяет семантику) и указания ключевого слова TABLE HINT только со ссылкой на таблицу, без указания INDEX.
USE AdventureWorks2012;
GO
EXEC sp_create_plan_guide
@name = N'Guide7',
@stmt = N'SELECT c.LastName, c.FirstName, e.JobTitle
FROM HumanResources.Employee AS e
JOIN Person.Person AS c ON e.BusinessEntityID = c.BusinessEntityID
WHERE OrganizationLevel = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, NOLOCK))';
GO