dicas de consulta (Transact-SQL)
As dicas de consulta especificam que as dicas indicadas devem ser usadas em toda a consulta. Elas afetam todos os operadores na instrução. Se UNION estiver envolvida na consulta principal, só a última consulta envolvendo uma operação UNION poderá ter a cláusula OPTION. As dicas de consulta são especificadas como parte da cláusula OPTION. Se uma ou mais dicas de consulta fizerem com que o otimizador de consulta não gere um plano válido, será emitido o erro 8622.
Aviso
Como o otimizador de consulta do SQL Server seleciona, normalmente, o melhor plano de execução para uma consulta, recomendamos usar dicas apenas como último recurso para desenvolvedores e administradores de banco de dados experientes.
Aplica-se a:
Aplica-se a: SQL Server (SQL Server 2008 até a versão atual), Banco de dados SQL do Windows Azure (versão inicial até a versão atual). |
Convenções da sintaxe Transact-SQL
Sintaxe
<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
| SNAPSHOT
| SPATIAL_WINDOW_MAX_CELLS = integer
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Argumentos
{ HASH | ORDER } GROUP
Especifica que as agregações descritas na cláusula GROUP BY ou DISTINCT da consulta devem usar hash ou ordenação.{ MERGE | HASH | CONCAT } UNION
Especifica que todas as operações UNION são executadas por mesclagem, hash ou concatenação de conjuntos de UNION. Se mais de uma dica de UNION for especificada, o otimizador de consulta selecionará a estratégia menos cara dentre as dicas especificadas.{ LOOP | MERGE | HASH } JOIN
Especifica que todas as operações de junção são executadas por LOOP JOIN, MERGE JOIN ou HASH JOIN na consulta inteira. Se mais de uma dica de junção for especificada, o otimizador selecionará a estratégia de junção menos cara dentre as permitidas.Se, na mesma consulta, uma dica de junção for especificada também na cláusula FROM para um par de tabelas específico, essa dica de junção terá precedência na junção das duas tabelas, embora as dicas de consulta ainda devam ser consideradas. Portanto, a dica de junção para o par de tabelas pode restringir apenas a seleção de métodos de junção permitidos na dica de consulta. Para obter mais informações, consulte dicas de junção (Transact-SQL).
EXPAND VIEWS
Especifica que as exibições indexadas são expandidas e o otimizador de consulta não considerará nenhuma exibição indexada como uma substituta de qualquer parte da consulta. Uma exibição é expandida quando o nome da exibição é substituído por sua definição no texto da consulta.Esta dica de consulta desabilita o uso direto de exibições indexadas e índices em exibições indexadas no plano de consulta.
A exibição indexada só não será expandida se a exibição receber referência direta na parte SELECT da consulta e se WITH (NOEXPAND) ou WITH (NOEXPAND, INDEX ( index_value [ ,...n ])) for especificado. Para obter mais informações sobre a dica de consulta WITH (NOEXPAND), consulte FROM.
Apenas as exibições na parte SELECT das instruções, inclusive aquelas nas instruções INSERT, UPDATE, MERGE e DELETE são afetadas pela dica.
FAST number_rows
Especifica que a consulta é otimizada para recuperação rápida dos primeiros number_rows. É um inteiro não negativo. Depois que o primeiro number_rows é retornado, a consulta continua a execução e produz seu conjunto de resultados completo.FORCE ORDER
Especifica que a ordem de junção indicada pela sintaxe de consulta é preservada durante a otimização da consulta. Usar FORCE ORDER não afeta o possível comportamento de reversão de função do otimizador de consulta.Dica
Em uma instrução MERGE, a tabela de origem é acessada antes da tabela de destino como a ordem de junção padrão, a menos que a cláusula WHEN SOURCE NOT MATCHED seja especificada.Especificar FORCE ORDER preserva esse comportamento padrão.
KEEP PLAN
Força o otimizador de consulta a relaxar o limite de recompilação estimado para uma consulta. O limite de recompilação estimado é o ponto no qual uma consulta é recompilada automaticamente quando o número calculado de alterações de colunas indexadas tiver sido efetuado em uma tabela por meio da execução da instrução UPDATE, DELETE, MERGE ou INSERT. Especificar KEEP PLAN assegura que uma consulta não seja recompilada tão frequentemente como quando há várias atualizações em uma tabela.KEEPFIXED PLAN
Força o otimizador de consulta a não recompilar uma consulta devido a alterações nas estatísticas. Especificar KEEPFIXED PLAN assegura que uma consulta seja recompilada apenas se o esquema das tabelas subjacentes for alterado ou se sp_recompile for executado em relação a essas tabelas.IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX
Aplica-se a: SQL Server 2012 a SQL Server 2014.
Impede a consulta de usar um índice columnstore xVelocity de memória otimizada não clusterizado. Se a consulta contiver a dica de consulta para evitar o uso do índice columnstore e uma dica de índice para usar um índice columnstore, as dicas entrarão em conflito e a consulta retornará um erro.
MAXDOP number
Aplica-se a: SQL Server 2008 a SQL Server 2014.
Substitui a opção de configuração max degree of parallelism de sp_configure e do Administrador de Recursos para a consulta que especifica essa opção. A dica de consulta MAXDOP pode exceder o valor configurado com sp_configure. Se MAXDOP exceder o valor configurado com o Administrador de Recursos, o Mecanismo de Banco de Dados usará o valor MAXDOP do Administrador de Recursos, descrito em ALTER WORKLOAD GROUP (Transact-SQL). Todas as regras semânticas usadas com a opção de configuração max degree of parallelism são aplicáveis ao usar a dica de consulta MAXDOP. Para obter mais informações, consulte Configurar a opção de configuração de servidor max degree of parallelism.
Aviso
Se MAXDOP estiver definido como 0, o servidor escolherá o max degree of parallelism.
MAXRECURSION number
Especifica o número máximo de recursões permitidas para esta consulta. number é um inteiro de não negativo entre 0 e 32767. Quando 0 é especificado, nenhum limite é aplicado. Se essa opção não for especificada, o limite padrão para o servidor será de 100.Quando o número especificado ou padrão de limite de MAXRECURSION é atingido durante a execução da consulta, a consulta é encerrada e um erro é retornado.
Por causa desse erro, todos os efeitos da instrução são revertidos. Se a instrução for do tipo SELECT, poderão ser retornados resultados parciais ou nenhum resultado. Eventuais resultados parciais retornados podem não incluir todas as linhas em níveis de recursão acima do nível de recursão máximo especificado.
Para obter mais informações, consulte WITH common_table_expression (Transact-SQL).
OPTIMIZE FOR ( @variable\_name { UNKNOWN | = literal_constant } [ , ...n ] )
Instrui o otimizador de consulta a usar um valor específico para uma variável local quando a consulta é compilada e otimizada. O valor só é usado durante a otimização, e não durante a execução das consultas.@variable\_name
É o nome de uma variável local usada em uma consulta para a qual um valor pode ser atribuído para uso com a dica de consulta OPTIMIZE FOR.UNKNOWN
Especifica que o otimizador de consulta usa dados estatísticos e não o valor inicial para determinar o valor de uma variável local durante a otimização da consulta.literal_constant
É um valor constante de literal a ser atribuído a @variable\_name para uso com a dica de consulta OPTIMIZE FOR. literal_constant é usado somente durante a otimização da consulta e não como o valor de @variable\_name durante a execução da consulta. literal_constant pode ser de qualquer tipo de dados de sistema SQL Server que pode ser expressado como uma constante literal. O tipo de dados de literal_constant deve ser implicitamente conversível no tipo de dados a que @variable\_name faz referência na consulta.
OPTIMIZE FOR pode anular o comportamento de detecção de parâmetro padrão do otimizador ou pode ser usado na criação de guias de plano. Para obter mais informações, consulte Recompilar um procedimento armazenado.
OPTIMIZE FOR UNKNOWN
Instrui o otimizador de consulta a usar dados estatísticos e não os valores iniciais para todas as variáveis locais quando a consulta é compilada e otimizada, incluindo parâmetros criados com parametrização forçada.Se OPTIMIZE FOR @variable\_name = literal_constant e OPTIMIZE FOR UNKNOWN forem usados na mesma dica de consulta, o otimizador de consulta usará a literal_constant especificada para um valor específico e UNKNOWN para o restante dos valores de variáveis. Os valores só são usados durante a otimização de consulta e não durante a execução das consultas.
PARAMETERIZATION { SIMPLE | FORCED }
Especifica as regras de parametrização que o otimizador de consulta do SQL Server aplica à consulta quando ela é compilada.Importante
A dica de consulta PARAMETERIZATION só pode ser especificada dentro de um guia de plano.Ela não pode ser especificada diretamente dentro de uma consulta.
SIMPLE instrui o otimizador de consulta a tentar parametrização simples. FORCED instrui o otimizador de consulta a tentar parametrização forçada. A dica de consulta PARAMETERIZATION é usada para substituir a configuração atual da opção SET do banco de dados PARAMETERIZATION dentro de um guia de plano. Para obter mais informações, consulte Especificar comportamento de parametrização de consulta usando guias de plano.
RECOMPILE
Instrui o Mecanismo de Banco de Dados do SQL Server a descartar o plano gerado para a consulta depois de sua execução, forçando o otimizador de consulta a recompilar um plano de consulta da próxima vez que a mesma consulta for executada. Sem especificar RECOMPILE, o Mecanismo de Banco de Dados armazena em cache os planos de consulta e os reutiliza. Ao compilar planos de consulta, a dica de consulta RECOMPILE usa os valores atuais de todas as variáveis locais na consulta e, se a consulta estiver dentro de um procedimento armazenado, os valores atuais serão passados para quaisquer parâmetros.RECOMPILE é uma alternativa útil à criação de um procedimento armazenado que utiliza a cláusula WITH RECOMPILE quando só um subconjunto de consultas dentro do procedimento armazenado, em vez de todo o procedimento armazenado, deve ser recompilado. Para obter mais informações, consulte Recompilar um procedimento armazenado. RECOMPILE também é útil para a criação de guias de plano.
ROBUST PLAN
Força o otimizador de consulta a tentar um plano que trabalhe para o tamanho máximo de linhas potenciais, possivelmente às custas do desempenho. Quando a consulta é processada, tabelas e operadores intermediários podem precisar armazenar e processar linhas maiores do que qualquer uma das linhas de entrada. As linhas podem ser tão grandes que, às vezes, o operador particular não consegue processá-las. Se isso ocorrer, o Mecanismo de Banco de Dados produzirá um erro durante a execução da consulta. Usando ROBUST PLAN, você instrui o otimizador de consulta a não considerar nenhum plano de consulta que possa encontrar esse problema.Se tal plano não for possível, o otimizador de consulta retornará um erro, em vez de adiar a detecção de erros para a execução da consulta. Linhas podem conter colunas de tamanho variável. O Mecanismo de Banco de Dados permite definir linhas com o tamanho potencial máximo para além da capacidade de processamento do Mecanismo de Banco de Dados. Geralmente, apesar do tamanho potencial máximo, um aplicativo armazena linhas cujos tamanhos reais estão dentro dos limites de processamento do Mecanismo de Banco de Dados. Se o Mecanismo de Banco de Dados encontrar uma linha longa demais, será retornado um erro de execução.
USE PLAN N**'xml_plan'**
Força o otimizador de consulta a usar um plano de consulta existente para uma consulta especificada por 'xml_plan'. USE PLAN não pode ser especificado com instruções INSERT, UPDATE, MERGE ou DELETE.TABLE HINT (exposed_object_name [ , <table_hint> [ [, ]...n ] ] )
Aplica a dica de tabela especificada à tabela ou exibição que corresponde ao exposed_object_name. É recomendável usar uma dica de tabela como dica de consulta apenas no contexto de um guia de plano.exposed_object_name pode ser uma das seguintes referências:
Quando um alias é usado para a tabela ou exibição na cláusula FROM da consulta, exposed_object_name é o alias.
Quando um alias não é usado, exposed_object_name é o correspondente exato da tabela ou exibição referida na cláusula FROM. Por exemplo, se a tabela ou exibição for referida por meio de um nome de duas partes, exposed_object_name será esse mesmo nome de duas partes.
Quando exposed_object_name é especificado sem também especificar uma dica de tabela, quaisquer índices especificados na consulta como parte de uma dica de tabela para o objeto é desconsiderado e o uso do índice é determinado pelo otimizador de consulta. Você pode usar essa técnica para eliminar o efeito de uma dica de tabela INDEX quando não puder modificar a consulta original. Consulte o exemplo J.
<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 | SNAPSHOT | SPATIAL_WINDOW_MAX_CELLS | TABLOCK | TABLOCKX | UPDLOCK | XLOCK }
É a dica de tabela a ser aplicada à tabela ou exibição que corresponde ao exposed_object_name como uma dica de consulta. Para obter uma descrição dessas dicas, consulte Dicas de tabela (Transact-SQL).Dicas de tabela diferentes de INDEX, FORCESCAN e FORCESEEK não são permitidas como dicas de consulta, a não ser que a consulta possua uma cláusula WITH que especifique a dica de tabela. Para obter mais informações, consulte Comentários.
Aviso
A especificação de FORCESEEK com parâmetros limita mais o número de planos que podem ser considerados pelo otimizador do que a especificação de FORCESEEK sem parâmetros.Isso pode resultar em um erro "Não é possível gerar o plano" em mais casos.Em uma versão futura, as modificações internas no otimizador talvez permitam a consideração de mais planos.
Comentários
Não podem ser especificadas dicas de consulta em uma instrução INSERT, exceto quando uma cláusula SELECT for usada dentro da instrução.
Só podem ser especificadas dicas de consulta na consulta de nível superior, e não em subconsultas. Quando uma dica de tabela é especificada como dica de consulta, ela pode ser especificada na consulta de nível superior ou em uma subconsulta; porém, o valor especificado para exposed_object_name na cláusula TABLE HINT deve corresponder exatamente ao nome exposto na consulta ou subconsulta.
Especificando dicas de tabela como dicas de consulta
É recomendável usar a dica de tabela INDEX, FORCESCAN ou FORCESEEK como dica de consulta apenas no contexto de um guia de plano. Guias de plano são úteis quando não é possível modificar a consulta original, por exemplo, por se tratar de um aplicativo de terceiros. A dica de consulta especificada na guia de plano é adicionada à consulta antes de ela ser compilada e otimizada. Para consultas ad hoc, use a cláusula TABLE HINT apenas ao testar instruções de guia de plano. Para todas as demais consultas ad hoc, é recomendável especificar essas dicas apenas como dicas de tabela.
Quando especificadas como uma dica de consulta, as dicas de tabela INDEX, FORCESCAN e FORCESEEK são válidas para os objetos a seguir:
Tabelas
Exibições
Exibições indexadas
Expressões de tabela comuns (a dica deve ser especificada na instrução SELECT cujo conjunto de resultados popula a expressão de tabela comum)
Exibições de gerenciamento dinâmico
Subconsultas nomeadas
As dicas de tabela INDEX, FORCESCAN e FORCESEEK podem ser especificadas como dicas de consulta para uma consulta que não tem dicas de tabela existentes ou podem ser usadas para substituir dicas INDEX, FORCESCAN ou FORCESEEK existentes na consulta, respectivamente. Dicas de tabela diferentes de INDEX, FORCESCAN e FORCESEEK não são permitidas como dicas de consulta, a não ser que a consulta possua uma cláusula WITH que especifique a dica de tabela. Nesse caso, será necessário especificar também uma dica correspondente como dica de consulta usando TABLE HIT na cláusula OPTION para preservar a semântica da consulta. Por exemplo, se a consulta contiver a dica de tabela NOLOCK, a cláusula OPTION no parâmetro @hints do guia de plano também deverá conter a dica NOLOCK. Consulte o exemplo K. Quando uma dica de tabela diferente de INDEX, FORCESCAN, ou FORCESEEK é especificada pela TABLEHINT na cláusula OPTION sem uma dica de consulta correspondente, ou vice-versa, o erro 8702 é gerado (indicando que a cláusula OPTION pode modificar a semântica da consulta), gerando falha na execução da consulta.
Exemplos
A.Usando MERGE JOIN
O exemplo a seguir especifica que a operação JOIN na consulta é executada por MERGE JOIN. O exemplo usa o banco de dados AdventureWorks2012 .
SELECT *
FROM Sales.Customer AS c
INNER JOIN Sales.CustomerAddress AS ca ON c.CustomerID = ca.CustomerID
WHERE TerritoryID = 5
OPTION (MERGE JOIN);
GO
B.Usando OPTIMIZE FOR
O exemplo a seguir instrui o otimizador de consulta a usar o valor 'Seattle' como variável local @city\_name e a usar valores estatísticos para determinar o valor da variável local @postal\_code ao otimizar a consulta. O exemplo usa o banco de dados AdventureWorks2012 .
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) );
C.Usando MAXRECURSION
MAXRECURSION pode ser usado para impedir que uma expressão de tabela comum recursiva malformada entre em loop infinito. O exemplo a seguir cria um loop infinito intencionalmente e usa a dica MAXRECURSION para limitar o número de níveis de recursão a dois. O exemplo usa o banco de dados AdventureWorks2012 .
--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
Depois que o erro de codificação é corrigido, MAXRECURSION já não é necessário.
D.Usando MERGE UNION
O exemplo a seguir usa a dica de consulta MERGE UNION. O exemplo usa o banco de dados AdventureWorks2012 .
SELECT *
FROM HumanResources.Employee AS e1
UNION
SELECT *
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
E.Usando HASH GROUP e FAST
O exemplo a seguir usa as dicas de consulta HASH GROUP e FAST. O exemplo usa o banco de dados AdventureWorks2012 .
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
F.Usando MAXDOP
O exemplo a seguir usa a dica de consulta MAXDOP. O exemplo usa o banco de dados AdventureWorks2012 .
Aplica-se a: SQL Server 2008 a SQL Server 2014. |
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);
G.Usando INDEX
O exemplo a seguir usa a dica INDEX. O primeiro exemplo especifica um único índice. O segundo exemplo especifica vários índices para uma única referência de tabela. Nos dois exemplos, uma vez que a dica INDEX é aplicada em uma tabela que usa um alias, a cláusula TABLE HINT também deve especificar o mesmo alias como nome do objeto exposto. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide1',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX (IX_Employee_ManagerID)))';
GO
EXEC sp_create_plan_guide
@name = N'Guide2',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e, INDEX(PK_Employee_EmployeeID, IX_Employee_ManagerID)))';
GO
H.Usando FORCESEEK
O exemplo a seguir usa a dica de tabela FORCESEEK. Como a dica INDEX é aplicada em uma tabela que usa um nome de duas partes, a cláusula TABLE HINT também deve especificar o mesmo nome de duas partes como nome do objeto exposto. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide3',
@stmt = N'SELECT c.LastName, c.FirstName, HumanResources.Employee.Title
FROM HumanResources.Employee
JOIN Person.Contact AS c ON HumanResources.Employee.ContactID = c.ContactID
WHERE HumanResources.Employee.ManagerID = 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
I.Usando várias dicas de tabela
O exemplo a seguir aplica a dica INDEX a uma tabela e a dica FORCESEEK a outra. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide4',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID ) )
, TABLE HINT ( c, FORCESEEK) )';
J.Usando TABLE HINT para substituir uma dica de tabela existente
O exemplo a seguir mostra como usar a dica TABLE HINT sem especificar uma dica para substituir o comportamento da dica de tabela INDEX especificada na cláusula FROM da consulta. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide5',
@stmt = N'SELECT e.ManagerID, c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e WITH (INDEX (IX_Employee_ManagerID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT(e))';
GO
K.Especificando dicas de tabela que afetam a semântica
O exemplo a seguir contém duas dicas de tabela na consulta: NOLOCK, que afeta a semântica, e INDEX, que não afeta a semântica. Para preservar a semântica da consulta, a dica NOLOCK é especificada na cláusula OPTIONS do guia de plano. Além da dica NOLOCK, as dicas INDEX e FORCESEEK são especificadas e substituem a dica INDEX, que não afeta a semântica, na consulta, quando a instrução é compilada e otimizada. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide6',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 3;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, INDEX( IX_Employee_ManagerID) , NOLOCK, FORCESEEK ))';
GO
O exemplo a seguir mostra um método alternativo para preservar a semântica da consulta e permitir que o otimizador escolha um índice diferente do índice especificado na dica de tabela. Isso é feito especificando-se a dica NOLOCK na cláusula OPTIONS (porque afeta a semântica) e a palavra-chave TABLE HINT com apenas uma referência de tabela e nenhuma dica INDEX. O exemplo usa o banco de dados AdventureWorks2012 .
EXEC sp_create_plan_guide
@name = N'Guide7',
@stmt = N'SELECT c.LastName, c.FirstName, e.Title
FROM HumanResources.Employee AS e
WITH (NOLOCK, INDEX (PK_Employee_EmployeeID))
JOIN Person.Contact AS c ON e.ContactID = c.ContactID
WHERE e.ManagerID = 2;',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION (TABLE HINT ( e, NOLOCK))';