Dicas de tabela (Transact-SQL)
Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do AzureBanco de Dados SQL no Microsoft Fabric
Dicas de tabela são usadas para substituir o comportamento padrão do otimizador de consulta durante a instrução DML (linguagem de manipulação de dados). Você pode especificar um método de bloqueio, um ou mais índices, uma operação de processamento de consulta, como uma verificação de tabela ou busca de índice, ou outras opções. As dicas de tabela são especificadas na cláusula FROM
da instrução DML e afetam apenas a tabela ou exibição referenciada nessa cláusula.
Cuidado
Como o otimizador de consulta do SQL Server normalmente seleciona o melhor plano de execução para uma consulta, é recomendável que desenvolvedores e administradores de banco de dados experientes usem as dicas apenas como um último recurso.
Aplica-se a:
Convenções de sintaxe do Transact-SQL
Sintaxe
WITH ( <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_value>
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
<table_hint_limited> ::=
{
KEEPIDENTITY
| KEEPDEFAULTS
| HOLDLOCK
| IGNORE_CONSTRAINTS
| IGNORE_TRIGGERS
| NOLOCK
| NOWAIT
| PAGLOCK
| READCOMMITTED
| READCOMMITTEDLOCK
| READPAST
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| SNAPSHOT
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
}
Argumentos
WITH ( <table_hint> ) [ [ , ] ...n ]
Com algumas exceções, há suporte para dicas de tabela na cláusula FROM
somente quando as dicas são especificadas com a palavra-chave WITH
. Dicas de tabela também devem ser especificadas com parênteses.
Importante
Omitir a palavra-chave WITH
é um recurso preterido: esse recurso será removido em uma versão futura do SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.
As seguintes dicas de tabela são permitidas com e sem a palavra-chave WITH
: NOLOCK
, READUNCOMMITTED
, UPDLOCK
, REPEATABLEREAD
, SERIALIZABLE
, READCOMMITTED
, TABLOCK
, TABLOCKX
, PAGLOCK
, ROWLOCK
, NOWAIT
, READPAST
, XLOCK
, SNAPSHOT
e NOEXPAND
. Quando essas dicas de tabela forem especificadas sem a palavra-chave WITH
, elas deverão ser especificadas sozinhas. Por exemplo:
FROM t (TABLOCK)
Quando a dica é especificada com outra opção, a dica deve ser especificada com a palavra-chave WITH
:
FROM t WITH (TABLOCK, INDEX(myindex))
É recomendável usar vírgulas entre dicas de tabela.
Importante
Separar dicas por espaços em vez de vírgulas é um recurso preterido: esse recurso será removido em uma versão futura do SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.
NOEXPAND
Especifica que qualquer exibição indexada não será expandida para acessar tabelas subjacentes quando o otimizador de consulta processar a consulta. O otimizador de consulta trata a exibição como uma tabela com índice clusterizado.
NOEXPAND
aplica-se apenas a exibições indexadas. Para obter mais informações, consulte Use NOEXPAND.
INDEX ( <index_value> [ , ...n ] ) | INDEX = ( <index_value> )
A sintaxe de INDEX()
especifica os nomes ou as IDs de um ou mais índices a serem usados pelo otimizador de consulta ao processar a instrução. A sintaxe INDEX =
alternativa especifica um único valor de índice. Apenas uma dica de índice por tabela pode ser especificada.
Se houver um índice clusterizado, INDEX(0)
forçará uma verificação de índice clusterizado e INDEX(1)
forçará uma verificação ou busca de índice clusterizado. Se não existir nenhum índice clusterizado, INDEX(0)
forçará uma verificação de tabela e INDEX(1)
será interpretado como um erro.
Se forem usados vários índices em apenas uma lista de índices, as duplicatas serão ignoradas e os demais índices listados serão usados para recuperar as linhas da tabela. A ordem dos índices na dica de índice é importante. Uma dica de vários índices também impõe o uso de AND de índice e o otimizador de consulta aplicará tantas condições quantas forem possíveis em cada índice acessado. Se a coleção de índices com dica não incluir todas as colunas referidas pela consulta, uma busca será executada para recuperar as colunas restantes depois que o Mecanismo de Banco de Dados do SQL Server recuperar todas as colunas indexadas.
Observação
Quando uma dica de índice que faz referência a vários índices for usada na tabela de fatos em uma junção em estrela, o otimizador ignorará a dica de índice e retornará uma mensagem de aviso. Além disso, index ORing não é permitido para uma tabela com uma dica de índice especificada.
O número máximo de índices na dica de tabela é de 250 índices não clusterizados.
KEEPIDENTITY
Aplicável somente em uma instrução INSERT
quando a opção BULK
é usada com OPENROWSET.
Especifica que o valor, ou valores, de identidade no arquivo de dados importado deve ser usado para a coluna de identidade. Se KEEPIDENTITY
não for especificado, os valores de identidade desta coluna serão verificados, mas não importados, e o otimizador de consulta atribuirá automaticamente valores exclusivos com base nos valores de propagação e incremento especificados durante a criação da tabela.
Importante
Se o arquivo de dados não contiver valores para a coluna de identidade na tabela ou exibição e a coluna de identidade não for a última coluna da tabela, você deverá ignorar a coluna de identidade. Para obter mais informações, consulte Usar um arquivo de formato para ignorar um campo de dados (SQL Server). Se uma coluna de identidade for ignorada com êxito, o otimizador de consulta atribuirá valores exclusivos automaticamente para a coluna de identidade nas linhas da tabela importada.
Para obter um exemplo que usa essa dica em uma instrução INSERT ... SELECT * FROM OPENROWSET(BULK...)
, consulte Manter valores de identidade ao importar dados em massa (SQL Server).
Para obter informações sobre como verificar o valor de identidade de uma tabela, consulte DBCC CHECKIDENT.
KEEPDEFAULTS
Aplicável somente em uma instrução INSERT
quando a opção BULK
é usada com OPENROWSET.
Especifica a inserção do valor padrão de uma coluna de tabela, se houver, em vez de NULL
quando o registro de dados não tem um valor para a coluna.
Para obter um exemplo que usa essa dica em uma instrução INSERT ... SELECT * FROM OPENROWSET(BULK...)
, consulte Manter valores nulos ou padrão durante a importação em massa (SQL Server).
FORCESEEK [ ( <index_value> ( <index_column_name> [ , ...n ] ) ) ]
Especifica que o otimizador de consulta usará apenas uma operação de busca de índice como o caminho de acesso aos dados na tabela ou exibição.
Observação
Começando com o SQL Server 2008 R2 (10.50.x) Service Pack 1, os parâmetros de índice também podem ser especificados. Nesse caso, o otimizador de consulta considera apenas as operações de busca de índice através do índice especificado, usando pelo menos as colunas de índice especificadas.
index_value
É o valor do nome ou da ID do índice. A ID do índice 0 (heap) não pode ser especificada. Para retornar o nome ou a ID do índice, confira a exibição de catálogo
sys.indexes
.index_column_name
É o nome da coluna de índice a ser incluída na operação de busca. Especificar
FORCESEEK
com parâmetros de índice é semelhante a usarFORCESEEK
com uma dicaINDEX
. Entretanto, você pode adquirir maior controle sobre o caminho de acesso usado pelo otimizador de consulta especificando o índice a ser pesquisado e as colunas de índice a serem consideradas na operação de busca. O otimizador pode considerar mais colunas, se necessário. Por exemplo, se um índice não clusterizado for especificado, o otimizador poderá optar por usar colunas de chave de índice clusterizado além das colunas especificadas.
A dica FORCESEEK
pode ser especificada das maneiras a seguir.
Sintaxe | Exemplo | Descrição |
---|---|---|
Sem um índice ou uma dica INDEX |
FROM dbo.MyTable WITH (FORCESEEK) |
O otimizador de consulta considera apenas as operações de busca de índice para acessar a tabela ou exibição através de qualquer índice relevante. |
Combinado com uma dica INDEX |
FROM dbo.MyTable WITH (FORCESEEK, INDEX (MyIndex)) |
O otimizador de consulta considera apenas as operações de busca de índice para acessar a tabela ou exibição através do índice especificado. |
Parametrizado especificando um índice e colunas do índice | FROM dbo.MyTable WITH (FORCESEEK (MyIndex (col1, col2, col3))) |
O otimizador de consulta considera apenas as operações de busca de índice para acessar a tabela ou exibição através do índice especificado, usando pelo menos as colunas de índice especificadas. |
Ao usar a dica FORCESEEK
(com ou sem parâmetros de índice), considere as seguintes diretrizes:
- A dica pode ser especificada como uma dica de tabela ou como uma dica de consulta. Para obter mais informações sobre dicas de consulta, consulte dicas de consulta (Transact-SQL).
- Para aplicar
FORCESEEK
a uma exibição indexada, a dicaNOEXPAND
também deve ser especificada. - A dica pode ser aplicada no máximo uma vez por tabela ou exibição.
- A dica não pode ser especificada para uma fonte de dados remota. O erro 7377 é retornado quando
FORCESEEK
é especificado com uma dica de índice e o erro 8180 é retornado quandoFORCESEEK
é usado sem uma dica de índice. - Se
FORCESEEK
não resultar em nenhum plano encontrado, o erro 8622 será retornado.
Quando FORCESEEK
for especificado com parâmetros de índice, as seguintes diretrizes e restrições se aplicarão:
- A dica não pode ser especificada para uma tabela que é o destino de uma instrução
INSERT
,UPDATE
ouDELETE
. - A dica não pode ser especificada em combinação com uma dica
INDEX
ou outra dicaFORCESEEK
. - Pelo menos uma coluna deve ser especificada e ela deve ser a coluna de chave à esquerda.
- Colunas de índice adicionais podem ser especificadas; entretanto, colunas de chave não podem ser ignoradas. Por exemplo, se o índice especificado contiver as colunas de chave
a
,b
ec
, a sintaxe válida incluiráFORCESEEK (MyIndex (a))
eFORCESEEK (MyIndex (a, b)
. A sintaxe inválida incluiriaFORCESEEK (MyIndex (c))
eFORCESEEK (MyIndex (a, c)
. - A ordem de nomes de coluna especificada na dica deve corresponder à ordem das colunas no índice referenciado.
- As colunas que não constam na definição de chave de índice não podem ser especificadas. Por exemplo, em um índice não clusterizado, apenas as colunas de chave de índice definidas podem ser especificadas. As colunas de chave clusterizado que são automaticamente incluídas no índice não podem ser especificadas, mas podem ser usadas pelo otimizador.
- Um índice columnstore xVelocity otimizado para memória não pode ser especificado como parâmetro de índice. O erro 366 é retornado.
- Modificar a definição de índice (por exemplo, adicionando ou removendo colunas) pode exigir modificações nas consultas que fazem referência a esse índice.
- A dica impede que o otimizador considere índices espaciais ou XML na tabela.
- A dica não pode ser especificada em combinação com a dica
FORCESCAN
. - Para índices particionados, a coluna de particionamento implicitamente adicionada pelo SQL Server não pode ser especificada na dica
FORCESEEK
.
Cuidado
A especificação de FORCESEEK
com parâmetros limita o número de planos que podem ser considerados pelo otimizador, mais do que a especificação de FORCESEEK
sem parâmetros. Isso pode fazer com que um erro de Plan cannot be generated
ocorra em mais casos.
FORCESCAN
Aplica-se a: SQL Server 2008 R2 (10.50.x) Service Pack 1 e versões posteriores
Especifica que o otimizador de consulta usará apenas uma operação de verificação de índice como o caminho de acesso na tabela ou exibição referenciada. A dica FORCESCAN
pode ser útil em consultas nas quais o otimizador menospreza o número de linhas afetadas e escolhe uma operação de busca em vez de uma operação de verificação. Quando isso ocorre, a quantidade de memória concedida para a operação é muito baixa e o desempenho da consulta é afetado.
FORCESCAN
pode ser especificado com ou sem uma dica INDEX
. Quando combinado com uma dica de índice (INDEX = index_name, FORCESCAN
), o otimizador de consulta considera apenas verificar caminhos de acesso por meio do índice especificado ao acessar a tabela referenciada.
FORCESCAN
pode ser especificado com a dica de índice INDEX(0)
para forçar uma operação de verificação de tabela na tabela base.
Para tabelas e índices particionados, FORCESCAN
é aplicado depois que as partições são eliminadas por meio da avaliação do predicado de consulta. Isso significa que a verificação é aplicada apenas às partições restantes e não à tabela inteira.
A dica FORCESCAN
tem as seguintes restrições:
- A dica não pode ser especificada para uma tabela que é o destino de uma instrução
INSERT
,UPDATE
ouDELETE
. - A dica não pode ser usada com mais de uma dica de índice.
- A dica impede que o otimizador de consulta considere índices espaciais ou XML na tabela.
- A dica não pode ser especificada para uma fonte de dados remota.
- A dica não pode ser especificada em combinação com a dica
FORCESEEK
.
HOLDLOCK
Equivalente a SERIALIZABLE
. Para obter mais informações, consulte SERIALIZABLE posteriormente neste artigo.
HOLDLOCK
se aplica somente à tabela ou exibição na qual ela é especificada e somente pela duração da transação definida pela instrução na qual ela é usada.
HOLDLOCK
não pode ser usado em uma instrução SELECT que inclua a opção FOR BROWSE
.
IGNORE_CONSTRAINTS
Aplicável somente em uma instrução INSERT
quando a opção BULK
é usada com OPENROWSET.
Especifica que a operação de importação em massa ignora quaisquer restrições na tabela. Por padrão, INSERT
verifica restrições exclusivas e verifica as restrições e restrições de chave primária e estrangeira. Quando IGNORE_CONSTRAINTS
é especificado para uma operação de importação em massa, INSERT
deve ignorar essas restrições em uma tabela de destino. Não é possível desabilitar restrições UNIQUE
, PRIMARY KEY
ou NOT NULL
.
Talvez você queira desabilitar restrições de CHECK
e FOREIGN KEY
se os dados de entrada contiver linhas que violam restrições. Ao desabilitar as restrições de CHECK
e FOREIGN KEY
, você pode importar os dados e, em seguida, usar instruções Transact-SQL para limpar os dados.
No entanto, quando as restrições CHECK
e FOREIGN KEY
são ignoradas, cada restrição ignorada na tabela é marcada como is_not_trusted
na exibição de catálogo sys.check_constraints ou sys.foreign_keys após a operação. Em algum ponto, verifique as restrições de toda a tabela. Se a tabela não estiver vazia antes da operação de importação em massa, o custo de revalidação da restrição poderá exceder o custo de aplicação de restrições de CHECK
e FOREIGN KEY
aos dados incrementais.
IGNORE_TRIGGERS
Aplicável somente em uma instrução INSERT
quando a opção BULK
é usada com OPENROWSET.
Especifica que qualquer gatilho definido na tabela será ignorado pela operação de importação em massa. Por padrão, INSERT
aplica gatilhos.
Use IGNORE_TRIGGERS
somente se o aplicativo não depender de nenhum gatilho e maximizar o desempenho for importante.
NOLOCK
Equivalente a READUNCOMMITTED
. Para obter mais informações, consulte READUNCOMMITTED posteriormente neste artigo.
Observação
Para instruções UPDATE
ou DELETE
: esse recurso será removido em uma versão futura do SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.
NOWAIT
Instrui o Mecanismo de Banco de Dados a retornar uma mensagem assim que um bloqueio for encontrado na tabela.
NOWAIT
é equivalente a especificar SET LOCK_TIMEOUT 0
para uma tabela designada. A dica NOWAIT
não funciona quando a dica TABLOCK
também é incluída. Para terminar uma consulta sem aguardar ao usar a dica TABLOCK
, preceda a consulta com SET LOCK_TIMEOUT 0;
.
PAGLOCK
Usa bloqueios de página onde bloqueios individuais são usados normalmente em linhas ou chaves ou onde um único bloqueio de tabela é usado normalmente. Por padrão, usa o modo de bloqueio adequado para a operação. Quando especificados em transações que operam no nível de isolamento de SNAPSHOT
, os bloqueios de página não são usados a menos que PAGLOCK
seja combinado com outras dicas de tabela que requerem bloqueios, como UPDLOCK
e HOLDLOCK
.
READCOMMITTED
Especifica que as operações de leitura estão em conformidade com as regras do nível de isolamento READ COMMITTED
usando bloqueio ou controle de versão de linha. Se a opção de banco de dados READ_COMMITTED_SNAPSHOT
for OFF
, o Mecanismo de Banco de Dados adquire bloqueios compartilhados à medida que os dados são lidos e libera esses bloqueios quando a operação de leitura é concluída. Se a opção de banco de dados READ_COMMITTED_SNAPSHOT
for ON
, o Mecanismo de Banco de Dados não adquirirá bloqueios e usará o controle de versão de linha. Para obter mais informações sobre níveis de isolamento, consulte SET TRANSACTION ISOLATION LEVEL.
Observação
Para instruções UPDATE
ou DELETE
: esse recurso será removido em uma versão futura do SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.
READCOMMITTEDLOCK
Especifica que as operações de leitura estão em conformidade com as regras do nível de isolamento READ COMMITTED
usando o bloqueio. O Mecanismo de Banco de Dados adquire bloqueios compartilhados conforme os dados são lidos e libera esses bloqueios quando a operação de leitura é concluída, independentemente da configuração da opção READ_COMMITTED_SNAPSHOT
do banco de dados. Para obter mais informações sobre níveis de isolamento, consulte SET TRANSACTION ISOLATION LEVEL. Essa dica não pode ser especificada na tabela de destino de uma instrução INSERT
; o erro 4140 é retornado.
READPAST
Especifica que o Mecanismo de Banco de Dados não lê linhas bloqueadas por outras transações. Quando READPAST
é especificado, os bloqueios no nível da linha são ignorados, ao contrário dos bloqueios no nível da página. Ou seja, o Mecanismo de Banco de Dados ignorará as linhas em vez de bloquear a transação atual até que os bloqueios sejam liberados. Por exemplo, suponhamos que a tabela T1
contenha uma única coluna de inteiros com os valores 1, 2, 3, 4, 5. Se a transação A alterar o valor de 3 para 8, mas ainda não foi confirmada, a instrução SELECT * FROM T1 (READPAST)
produzirá os valores 1, 2, 4, 5.
READPAST
é usado principalmente para reduzir a contenção de bloqueio ao implementar uma fila de trabalho que usa uma tabela do SQL Server. Um leitor de fila que usa READPAST
ignora entradas da fila bloqueadas por outras transações, passando para a próxima entrada disponível da fila, sem precisar esperar até que outras transações liberem seus bloqueios.
READPAST
pode ser especificada para qualquer tabela referenciada em uma instrução UPDATE
ou DELETE
e qualquer tabela referenciada em uma cláusula FROM
. Quando especificado em uma instrução UPDATE
, READPAST
é aplicado somente ao ler dados para identificar quais registros atualizar, independentemente de onde na instrução é especificada.
READPAST
não pode ser especificado para tabelas na cláusula INTO
de uma instrução INSERT
. As operações de atualização ou exclusão que usam READPAST
podem ser bloqueadas ao ler chaves estrangeiras ou exibições indexadas ou ao modificar índices secundários.
READPAST
só pode ser especificado em transações que operam nos níveis de isolamento READ COMMITTED
ou REPEATABLE READ
. Quando especificados em transações que operam no nível de isolamento de SNAPSHOT
, READPAST
devem ser combinados com outras dicas de tabela que exigem bloqueios, como UPDLOCK
e HOLDLOCK
.
A dica de tabela READPAST
não pode ser especificada quando a opção READ_COMMITTED_SNAPSHOT
banco de dados é definida como ON
e qualquer uma das seguintes condições é verdadeira:
- O nível de isolamento da transação da sessão é
READ COMMITTED
. - A dica de tabela
READCOMMITTED
também é especificada na consulta.
Para especificar a dica READPAST
nesses casos, remova a dica de tabela READCOMMITTED
, se ela estiver presente, e inclua a dica de tabela READCOMMITTEDLOCK
na consulta.
READUNCOMMITTED
Especifica que leituras sujas são permitidas. Nenhum bloqueio compartilhado é emitido para impedir que outras transações modifiquem dados lidos pela transação atual, e bloqueios exclusivos definidos por outras transações não impedem que a transação atual leia os dados bloqueados. Permitir leituras sujas pode provocar maior simultaneidade, mas à custa da leitura de modificações de dados que, em seguida, serão revertidas por outras transações. Isso pode gerar erros para sua transação, apresentar aos usuários dados que nunca foram confirmados ou fazer com que os usuários vejam registros duas vezes (ou não).
As sicas READUNCOMMITTED
e NOLOCK
se aplicam apenas a bloqueios de dados. Todas as consultas, incluindo consultas com dicas de READUNCOMMITTED
e NOLOCK
, adquirem bloqueios de Sch-S (estabilidade do esquema) durante a compilação e a execução. Por causa disso, as consultas são bloqueadas quando uma transação simultânea mantém um bloqueio Sch-M (modificação de esquema) na tabela. Por exemplo, uma operação DDL (Linguagem de Definição de Dados) adquire um bloqueio Sch-M antes de modificar as informações do esquema da tabela. Todas as consultas simultâneas, incluindo consultas em execução com dicas de READUNCOMMITTED
ou NOLOCK
, são bloqueadas ao tentar adquirir um bloqueio de Sch-S. Da mesma forma, uma consulta que mantém um bloqueio Sch-S bloqueará uma transação simultânea que tentar adquirir um bloqueio Sch-M.
READUNCOMMITTED
e NOLOCK
não podem ser especificados para tabelas modificadas por operações de inserção, atualização ou exclusão. O otimizador de consulta do SQL Server ignora as dicas de READUNCOMMITTED
e NOLOCK
na cláusula FROM
que se aplicam à tabela de destino de uma instrução UPDATE
ou DELETE
.
Observação
O suporte para uso das dicas de READUNCOMMITTED
e NOLOCK
na cláusula FROM
que se aplicam à tabela de destino de uma instrução UPDATE
ou DELETE
será removido em uma versão futura do SQL Server. Evite usar essas dicas nesse contexto em desenvolvimentos novos e planeje modificar aplicativos que as usam atualmente.
Você pode minimizar a contenção de bloqueio ao proteger as transações contra leituras sujas de modificações de dados não confirmadas usando qualquer uma das seguintes opções:
- O nível de isolamento
READ COMMITTED
com a opção de banco de dadosREAD_COMMITTED_SNAPSHOT
definidaON
. - O nível de isolamento
SNAPSHOT
.
Para obter mais informações sobre níveis de isolamento, consulte SET TRANSACTION ISOLATION LEVEL.
Observação
Se você receber mensagem de erro 601 quando READUNCOMMITTED
for especificado, resolva-a como faria com um erro de deadlock (mensagem de erro 1205) e tente novamente sua instrução.
REPEATABLEREAD
Especifica que uma verificação é executada com a mesma semântica de bloqueio que uma transação em execução em REPEATABLE READ
nível de isolamento. Para obter mais informações sobre níveis de isolamento, consulte SET TRANSACTION ISOLATION LEVEL.
ROWLOCK
Especifica que bloqueios de linha serão usados quando os bloqueios de página ou de tabela forem usados normalmente. Quando especificados em transações que operam no nível de isolamento de SNAPSHOT
, os bloqueios de linha não são usados a menos que ROWLOCK
seja combinado com outras dicas de tabela que requerem bloqueios, como UPDLOCK
e HOLDLOCK
.
ROWLOCK
não pode ser usado com uma tabela que tenha um índice columnstore clusterizado. O exemplo a seguir retorna o erro 651 ao aplicativo.
UPDATE [dbo].[FactResellerSalesXL_CCI] WITH (ROWLOCK)
SET UnitPrice = 50
WHERE ProductKey = 150;
SERIALIZABLE
Equivalente a HOLDLOCK
. Torna bloqueios compartilhados mais restritivos ao mantê-los até que uma transação seja concluída, em vez de liberar o bloqueio compartilhado assim que a tabela ou página de dados requerida não seja mais necessária, quer a transação tenha sido concluída ou não. A verificação é executada com a mesma semântica da transação que está sendo executada no nível de isolamento SERIALIZABLE
. Para obter mais informações sobre níveis de isolamento, consulte SET TRANSACTION ISOLATION LEVEL.
SNAPSHOT
Aplica-se a: SQL Server 2014 (12.x) e versões posteriores
A tabela com otimização de memória é acessada sob o isolamento SNAPSHOT
.
SNAPSHOT
só pode ser usado com tabelas com otimização de memória (não com tabelas baseadas em disco), conforme visto no exemplo a seguir. Para obter mais informações, confira Introdução às tabelas com otimização de memória.
SELECT *
FROM dbo.Customers AS c WITH (SNAPSHOT)
LEFT OUTER JOIN dbo.[Order History] AS oh
ON c.customer_id = oh.customer_id;
SPATIAL_WINDOW_MAX_CELLS = <integer_value>
Aplica-se a: SQL Server 2012 (11.x) e versões posteriores
Especifica o número máximo de células para usar para fazer um mosaico de geometria ou objeto de geografia. <integer_value> é um valor entre 1 e 8192.
Esta opção permite ajustar o tempo de execução de consulta ajustando o intercâmbio entre o tempo de execução de filtro primário e secundário. Um número maior reduz o tempo de execução de filtro secundário, mas aumenta hora de filtro de execução primária e um número menor diminui tempo de execução de filtro primário, mas aumenta a execução de filtro secundária. Para dados espaciais mais densos, um número mais alto deve gerar um tempo de execução mais rápido dando uma aproximação melhor com o filtro primário e reduzindo o tempo de execução de filtro secundário. Para dados mais esparsos, um número inferior diminui o tempo de execução do filtro primário.
Essa opção funciona para mosaicos de grade manuais e automáticos.
TABLOCK
Especifica que o bloqueio adquirido seja aplicado no nível de tabela. O tipo de bloqueio que é adquirido depende da instrução que está sendo executada. Por exemplo, uma instrução SELECT
pode adquirir um bloqueio compartilhado. Ao especificar TABLOCK
, o bloqueio compartilhado é aplicado à tabela inteira e não no nível de linha ou página. Se HOLDLOCK
também for especificado, o bloqueio de tabela será mantido até o final da transação.
Ao importar dados para um heap usando a instrução INSERT INTO <target_table> SELECT <columns> FROM <source_table>
, você pode habilitar o registro em log mínimo e bloqueio ideal da instrução, especificando a dica TABLOCK
para a tabela de destino. Além disso, o modelo de recuperação do banco de dados deve ser definido como simples ou bulk-logged. A dica TABLOCK
também permite inserções paralelas para heaps ou índices columnstore clusterizados. Para obter mais informações, consulte INSERT.
Quando usado com o provedor de conjuntos de linhas em massa OPENROWSET para importar dados em uma tabela, o TABLOCK
permite que vários clientes carreguem dados simultaneamente na tabela de destino com o registro em log e o bloqueio otimizados. Para obter mais informações, consulte pré-requisitos para registro em log mínimo emde importação em massa.
TABLOCKX
Especifica que um bloqueio exclusivo será usado na tabela.
UPDLOCK
Especifica que bloqueios de atualização serão usados e mantidos até que a transação seja concluída. O UPDLOCK
utiliza bloqueios de atualização apenas em operações de leitura no nível de linha ou de página. Se UPDLOCK
for combinado com TABLOCK
, ou se um bloqueio em nível de tabela for usado por outro motivo, um bloqueio (X) exclusivo será usado.
Quando UPDLOCK
é especificado, as dicas em nível de isolamento READCOMMITTED
e READCOMMITTEDLOCK
são ignoradas. Por exemplo, se o nível de isolamento da sessão for definido como SERIALIZABLE
e uma consulta especificar (UPDLOCK
e READCOMMITTED
), a dica READCOMMITTED
será ignorada e a transação será executada usando o nível de isolamento SERIALIZABLE
.
XLOCK
Especifica que bloqueios exclusivos serão usados e mantidos até que a transação seja concluída. Se especificados com ROWLOCK
, PAGLOCK
ou TABLOCK
, os bloqueios exclusivos serão aplicados ao nível adequado de granularidade.
Comentários
As dicas de tabela serão ignoradas se a tabela não for acessada pelo plano de consulta. Isso pode ser causado pelo otimizador que opta por não acessar a tabela ou porque uma exibição indexada é acessada. Neste último caso, o acesso a uma exibição indexada pode ser evitado usando a dica de consulta OPTION (EXPAND VIEWS)
.
Todas as dicas de bloqueio são propagadas para todas as tabelas e exibições que são acessadas pelo plano de consulta, incluindo tabelas e exibições referenciadas em uma exibição. Além disso, o SQL Server executa os testes de consistência de bloqueio correspondentes.
Dicas de bloqueio ROWLOCK
, UPDLOCK
e XLOCK
que adquirem bloqueios no nível de linha podem colocar bloqueios em chaves de índice em vez das linhas de dados reais. Por exemplo, se uma tabela tiver um índice não clusterizado e uma instrução SELECT
usando uma dica de bloqueio for tratada por um índice de cobertura, um bloqueio será adquirido na chave de índice no índice de cobertura e não na linha de dados na tabela base.
Se a tabela contiver colunas computadas por expressões ou funções que acessam colunas em outras tabelas, as dicas de tabela não serão usadas nessas tabelas e não serão propagadas. Por exemplo, uma dica de tabela NOLOCK
é especificada em uma tabela na consulta. Essa tabela contém colunas computadas que são computadas por uma combinação de expressões e funções que acessam colunas de outras tabelas. As tabelas referenciadas pelas expressões e funções não usam a dica de tabela NOLOCK
quando acessadas.
O SQL Server não permite mais de uma dica de tabela de cada um dos seguintes grupos para cada tabela na cláusula FROM
:
- Dicas de granularidade:
PAGLOCK
,NOLOCK
,READCOMMITTEDLOCK
,ROWLOCK
,TABLOCK
ouTABLOCKX
. - Dicas de nível de isolamento:
HOLDLOCK
,NOLOCK
,READCOMMITTED
,REPEATABLEREAD
ouSERIALIZABLE
.
Dicas de índice filtrado
Um índice filtrado pode ser usado como uma dica de tabela, mas faz com que o otimizador de consulta gere o erro 8622 se ele não abrange todas as linhas selecionadas pela consulta. O seguinte exemplo é uma dica de índice filtrado inválida. O exemplo cria o índice filtrado FIBillOfMaterialsWithComponentID
e o usa como uma dica de índice para uma instrução SELECT
. O predicado do índice filtrado inclui linhas de dados para ComponentIDs 533, 324 e 753. O predicado da consulta também inclui linhas de dados para os ComponentIDs 533, 324 e 753, mas estende o conjunto de resultados para incluir os ComponentIDs 855 e 924 que não estão no índice filtrado. Portanto, o otimizador de consulta não pode usar a dica de índice filtrado e gera o erro 8622. Para obter mais informações, consulte Criar índices filtrados.
IF EXISTS (SELECT name FROM sys.indexes
WHERE name = N'FIBillOfMaterialsWithComponentID'
AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithComponentID
ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED INDEX [FIBillOfMaterialsWithComponentID]
ON Production.BillOfMaterials(ComponentID, StartDate, EndDate)
WHERE ComponentID IN (533, 324, 753);
GO
SELECT StartDate, ComponentID
FROM Production.BillOfMaterials
WITH (INDEX (FIBillOfMaterialsWithComponentID))
WHERE ComponentID IN (533, 324, 753, 855, 924);
GO
O otimizador de consulta não considerará uma dica de índice se as opções de SET
não tiverem os valores necessários para índices filtrados. Para obter mais informações, consulte CREATE INDEX.
Usar NOEXPAND
NOEXPAND
se aplica apenas a exibições indexadas. Uma exibição indexada é uma exibição com um índice clusterizado exclusivo criado nela. Se uma consulta tiver referências a colunas presentes em uma exibição indexada e em tabelas base, e o otimizador de consulta determinar que o uso da exibição indexada oferece o melhor método para a execução da consulta, o otimizador de consulta usará o índice na exibição. Essa funcionalidade é chamada de correspondência de exibição indexada. Antes do SQL Server 2016 (13.x) com o Service Pack 1, o uso automático de uma exibição indexada pelo otimizador de consulta só tem suporte em edições específicas do SQL Server. No SQL Server 2016 (13.x) com o Service Pack 1 e versões posteriores, todas as edições dão suporte ao uso automático de uma exibição indexada. O Banco de Dados SQL do Azure e a Instância Gerenciada de SQL do Azure também oferecem suporte ao uso automático de exibições indexadas sem especificar a dica NOEXPAND
.
Para obter mais informações, consulte Guia da Arquitetura de Processamento de Consultas.
Para obter uma lista dos recursos compatíveis com as edições do SQL Server no Windows, consulte:
- Edições e recursos com suporte do SQL Server 2022
- Edições e recursos com suporte do SQL Server 2019
- Edições e recursos com suporte do SQL Server 2017
- Edições e recursos com suporte do SQL Server 2016
No entanto, para que o otimizador de consulta considere exibições indexadas para correspondência ou use uma exibição indexada referenciada com a dica NOEXPAND
, as opções de SET
a seguir devem ser definidas como ON
.
- ANSI_NULLS
- ANSI_PADDING
- ANSI_WARNINGS
- ARITHABORT 1
- CONCAT_NULL_YIELDS_NULL
- QUOTED_IDENTIFIER
1ARITHABORT
é implicitamente definido como ON
quando ANSI_WARNINGS
é definido como ON
. Portanto, você não precisa ajustar essa configuração manualmente.
Além disso, a opção NUMERIC_ROUNDABORT
deve ser definida como OFF
.
Para forçar o otimizador de consulta a usar um índice em uma exibição indexada, especifique a opção NOEXPAND
. Essa dica poderá ser usada apenas se a exibição também estiver nomeada na consulta. O SQL Server não fornece uma dica para forçar uma exibição indexada específica a ser usada em uma consulta que não nomeie a exibição diretamente na cláusula FROM
. No entanto, o otimizador de consulta considera o uso de exibições indexadas, mesmo que elas não sejam referenciadas diretamente na consulta. O Mecanismo de Banco de Dados do SQL Server só cria estatísticas automaticamente em uma exibição indexada quando uma dica de tabela NOEXPAND
é usada. A omissão dessa dica pode resultar em avisos de plano de execução sobre as estatísticas ausentes que não podem ser resolvidas com a criação manual de estatísticas.
Durante a otimização de consulta, o Mecanismo de Banco de Dados usa as estatísticas de exibição que foram criadas de maneira automática ou manual quando a consulta referenciar a exibição diretamente e a dica NOEXPAND
for usada.
Usar uma dica de tabela como uma dica de consulta
Dicas de tabela também podem ser especificadas como uma dica de consulta usando a cláusula OPTION (TABLE HINT)
. É recomendável usar uma dica de tabela como uma dica de consulta apenas no contexto de um guia de plano. Para consultas ad hoc, especifique essas dicas apenas como dicas de tabela. Para obter mais informações, consulte dicas de consulta.
Permissões
As dicas KEEPIDENTITY
, IGNORE_CONSTRAINTS
e IGNORE_TRIGGERS
exigem permissões ALTER
na tabela.
Exemplos
a. Usar a dica TABLOCK para especificar um método de bloqueio
O exemplo a seguir especifica que um bloqueio compartilhado é feito na tabela Production.Product
no banco de dados AdventureWorks2022 e é mantido até o final da instrução UPDATE
.
UPDATE Production.Product WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO
B. Usar a dica FORCESEEK para especificar uma operação de busca de índice
O exemplo a seguir usa a dica FORCESEEK
sem especificar um índice para forçar o otimizador de consulta a executar uma operação de busca de índice na tabela Sales.SalesOrderDetail
do banco de dados AdventureWorks2022.
SELECT *
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESEEK)
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
GO
O exemplo a seguir usa a dica FORCESEEK
com um índice para forçar o otimizador de consulta a executar uma operação de busca de índice no índice e na coluna de índice especificados.
SELECT h.SalesOrderID,
h.TotalDue,
d.OrderQty
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d
WITH (FORCESEEK (PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID (SalesOrderID)))
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
GO
C. Usar a dica FORCESCAN para especificar uma operação de verificação de índice
O exemplo a seguir usa a dica FORCESCAN
para forçar o otimizador de consultas a executar uma operação de verificação na tabela Sales.SalesOrderDetail
do banco de dados AdventureWorks2022.
SELECT h.SalesOrderID,
h.TotalDue,
d.OrderQty
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d WITH (FORCESCAN)
ON h.SalesOrderID = d.SalesOrderID
WHERE h.TotalDue > 100
AND (d.OrderQty > 5
OR d.LineTotal < 1000.00);
Conteúdo relacionado
- OPENROWSET (Transact-SQL)
- dicas (Transact-SQL)
- dicas de consulta (Transact-SQL)