Efeito da dica NOLOCK nas instruções SELECT

199

Eu acho que a verdadeira questão é:

Se eu não me importo com leituras sujas, adicionar a dica with (NOLOCK) a uma instrução SELECT afetará o desempenho de:

  1. a instrução SELECT atual
  2. outras transações contra a tabela especificada

Exemplo:

Select * 
from aTable with (NOLOCK)
Bob Probst
fonte
3
Essas respostas de SO e DBA são um pouco mais claras sobre o que realmente está acontecendo.
Trisped

Respostas:

289

1) Sim , selecione comNOLOCK será concluída mais rapidamente que uma seleção normal.

2) Sim , uma seleção com NOLOCKpermitirá que outras consultas na tabela efetuada sejam concluídas mais rapidamente do que uma seleção normal.

Por que isso seria?

NOLOCKnormalmente (dependendo do mecanismo do banco de dados) significa me fornecer seus dados, e eu não me importo em que estado eles estão, e não me importo em mantê-los imóveis enquanto você os lê. É tudo ao mesmo tempo mais rápido, menos intensivo em recursos e muito, muito perigoso.

Você deve ser avisado para nunca fazer uma atualização ou executar algo crítico no sistema, ou onde a correção absoluta seja necessária usando dados originados de uma NOLOCKleitura. É absolutamente possível que esses dados contenham linhas que foram excluídas durante a execução da consulta ou que foram excluídas em outras sessões que ainda não foram finalizadas. É possível que esses dados incluam linhas que foram parcialmente atualizadas. É possível que esses dados contenham registros que violem restrições de chave estrangeira. É possível que esses dados excluam linhas que foram adicionadas à tabela, mas ainda não foram confirmadas.

Você realmente não tem como saber qual é o estado dos dados.

Se você está tentando obter coisas como uma contagem de linhas ou outros dados de resumo onde alguma margem de erro é aceitável, NOLOCKé uma boa maneira de aumentar o desempenho dessas consultas e evitar que elas afetem negativamente o desempenho do banco de dados.

Sempre use a NOLOCKdica com muito cuidado e trate os dados que eles retornam com suspeita.

tom.dietrich
fonte
Obrigado. Isso é o que eu suponho, mas fui questionado sobre isso por um colega e minha pesquisa inicial me fez questionar a mim mesmo. A documentação do SQLServer 2005 diz que com NOLOCK é o esquema de bloqueio padrão para todas as instruções de seleção! Eu acho que, em seguida, que as minhas sugestões seria redundante ...
Bob Probst
2
... 2005 e não tem nenhum efeito. Estamos executando o ano 2000 (graças ao nosso fornecedor) e não há nenhuma declaração semelhante na documentação.
Bob Probst
4
Seu amigo precisa ler a documentação. Tabela Hint (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA
9
Nota lateral: se isso fosse verdade, seria um caos absoluto.
DBA de Pittsburgh
1
Os pontos 1 e 2 precisam ser restritos a 1) "... quando uma ação de inserção / atualização / exclusão está pendente na tabela ." e 2) "... permitirá inserir / atualizar / excluir consultas contra ...". Eu (preferência pessoal) mudaria instâncias de "mais rápido" para "mais cedo", pois a diferença está aguardando a conclusão de outro processo.
Trisped
61

NOLOCK torna a maioria das instruções SELECT mais rápidas, devido à falta de bloqueios compartilhados. Além disso, a falta de emissão dos bloqueios significa que os gravadores não serão impedidos pelo seu SELECT.

NOLOCK é funcionalmente equivalente a um nível de isolamento de READ UNCOMMITTED. A principal diferença é que você pode usar o NOLOCK em algumas tabelas, mas não em outras, se desejar. Se você planeja usar NOLOCK em todas as tabelas em uma consulta complexa, é mais fácil usar SET TRANSACTION ISOLATION LEAD UNCOMMITTED, porque você não precisa aplicar a dica a todas as tabelas.

Aqui estão informações sobre todos os níveis de isolamento à sua disposição, bem como dicas de tabela.

DEFINIR O NÍVEL DE ISOLAMENTO DA TRANSAÇÃO

Dica de tabela (Transact-SQL)

Pittsburgh DBA
fonte
2
Eu concordo, mas não completamente; é importante ressaltar que uma dica NO LOCK / READ UNCOMMITTED na verdade não melhora a velocidade da consulta, mas mais ainda faz com que ela pareça mais rápida porque não precisa aguardar a conclusão das consultas anteriores. Realmente, a consulta parece mais rápida do que é mais rápida (eu acho).
Möoz 7/08/13
1
@BorhanMooz Bem, há a economia de não precisar solicitar bloqueios do gerenciador de bloqueios. Mesmo se não houver outras consultas aguardando, isso tem um custo e uma sobrecarga de memória.
Pittsburgh DBA
1
Eu estava discutindo isso com alguns dos meus colegas de trabalho. Pelo que entendi, uma consulta usando uma dica WITH (NOLOCK) ainda exige a obtenção de um bloqueio compartilhado por esquema ( mssqltips.com/sqlservertip/2470/… ).
Möoz 08/08/13
1
Sim, mas não milhares de bloqueios compartilhados em páginas ou extensões. Um bloqueio de esquema é UM bloqueio, não MILHARES. Se queremos ser pedantes, podemos continuar a debater isso, mas sim, haverá uma quantidade mínima de sobrecarga de bloqueio. As economias são significativas. Faça as contas sobre isso: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA
6

Vai ser mais rápido porque não precisa esperar pelos bloqueios

StingyJack
fonte
Quão rápido? Você poderia fornecer algum número de melhoria de velocidade?
Eugeniu Torica
5
"Quanto custa" depende do que você está fazendo especificamente com seus dados e de quanto tempo você normalmente espera pela aquisição de um bloqueio.
StingyJack 19/04
A única referência correta é aquela que você cria e executa. O que todo mundo diz é tão bom quanto "o cheque está no correio". Eu já provei muitos mitos e suposições errados muitas vezes, executando meus próprios benchmarks.
TravisO
^ @TravisO - está completamente correto. O NOLOCK foi executado mais lentamente algumas vezes. Não inteiramente certo porque, mas eu estou usando que quando a resolução de problemas e eu não quero negativamente (mais) afetar a produção
StingyJack
2
  • A resposta é Sim se a consulta for executada várias vezes ao mesmo tempo, porque cada transação não precisará aguardar a conclusão das outras. No entanto, se a consulta for executada uma vez por si só, a resposta será Não.

  • Sim . Existe uma probabilidade significativa de que o uso cuidadoso do WITH (NOLOCK) acelere o banco de dados em geral. Isso significa que outras transações não precisarão esperar a conclusão dessa instrução SELECT, mas, por outro lado, outras transações ficarão mais lentas, pois agora eles estão compartilhando seu tempo de processamento com uma nova transação.

Cuidado para usar apenasWITH (NOLOCK) instruções SELECT em tabelas que possuem um índice em cluster.

WITH (NOLOCK) é frequentemente explorado como uma maneira mágica de acelerar transações de leitura de banco de dados.

O conjunto de resultados pode conter linhas que ainda não foram confirmadas, que geralmente são revertidas posteriormente.

Se WITH (NOLOCK) for aplicado a uma tabela que possui um índice não clusterizado, os índices de linha poderão ser alterados por outras transações, à medida que os dados da linha estiverem sendo transmitidos para a tabela de resultados. Isso significa que o conjunto de resultados pode estar faltando linhas ou exibir a mesma linha várias vezes.

READ COMMITTED adiciona um problema adicional em que os dados são corrompidos em uma única coluna em que vários usuários alteram a mesma célula simultaneamente.

WonderWorker
fonte