NOLOCK é sempre ruim?

34

Sou desenvolvedor de relatórios e deseja tornar minhas consultas o mais eficiente possível. Eu costumava trabalhar com um DBA que me dizia - acredito que estava sempre lidando com relatórios em um servidor de produção - para usar NOLOCKem todas as consultas.

Agora, trabalho com um DBA que baniu NOLOCKsob qualquer circunstância - mesmo quando um relatório meu (devido a uma considerável falta de índices em algumas tabelas) está parando a replicação e as atualizações do sistema. Na minha opinião, neste caso, a NOLOCKseria uma coisa boa.

Como a maior parte do meu treinamento em SQL possui vários DBAs com opiniões muito diferentes, eu queria pedir isso para uma ampla variedade de DBAs.

DataGirl
fonte
11
O outro lado desta discussão: dba.stackexchange.com/q/2684/2660
Nick Chammas

Respostas:

30

Se o seu relatório bloquear atualizações de que seu DBA está certo: você absolutamente não deve usá-lo NOLOCK. O próprio fato de que não são conflitos é uma clara indicação de que se você iria usar leituras sujas que se obtém relatórios incorretos.

Na minha opinião, sempre existem alternativas melhores do que NOLOCK:

  • Suas tabelas de produção são lidas apenas em vigor e nunca são modificadas? Marque o banco de dados somente leitura!
  • Verificações de tabela causam conflitos de bloqueio? Indexar as tabelas adequadamente, os benefícios são múltiplos.
  • Não consegue modificar / não sabe indexar adequadamente? Use ISOLAMENTO DO INSTANTÂNEO .
  • Não é possível alterar o aplicativo para usar o instantâneo? Ative a leitura instantânea confirmada !
  • Você mediu o impacto do controle de versão de linha e tem evidências de que isso afeta o desempenho? Você não pode indexar os dados? e você está bem com relatórios incorretos ? Então, no mínimo, faça um favor e use a si mesmo SET TRANSACTION ISOLATION LEVEL, não uma dica de consulta. Será mais fácil corrigir posteriormente o nível de isolamento em vez de modificar todas as consultas.
Remus Rusanu
fonte
6
Cuidado: ativar a captura instantânea de leitura confirmada pode quebrar algum código.
AK
33

Nem sempre é ruim.

Obviamente, ele permite a leitura de valores não confirmados (que podem ser revertidos e, portanto, nunca existiram logicamente), além de permitir fenômenos como a leitura de valores várias vezes ou não.

Os únicos níveis de isolamento que garantem que você não encontrará essas anomalias são serializáveis ​​/ instantâneos. Em valores de leitura repetíveis, pode ser perdida se uma linha for movida (devido a uma atualização de chave) antes da varredura chegar a essa linha, em valores confirmados de leitura poderão ser lidos duas vezes se uma atualização de chave fizer com que uma linha lida anteriormente avance.

nolockNo entanto, é mais provável que esses problemas ocorram porque, por padrão, nesse nível de isolamento, ele usará uma verificação ordenada de alocação quando estima que há mais de 64 páginas para serem lidas . Assim como a categoria de problemas que surgem quando as linhas se movem entre as páginas devido às atualizações da chave de índice, essas verificações ordenadas de alocação também são vulneráveis ​​a problemas com divisões de página (onde as linhas podem ser perdidas se a página recém-alocada estiver mais cedo no arquivo que o ponto) já digitalizados ou lidos duas vezes se uma página já digitalizada for dividida em uma página posterior do arquivo).

Pelo menos para consultas simples (tabela única), é possível desencorajar o uso dessas verificações e obter uma verificação ordenada por chave nolock, simplesmente adicionando um ORDER BY index_keyà consulta para que a Orderedpropriedade da IndexScanseja true.

Mas se o seu aplicativo de relatórios não precisar de números absolutamente precisos e puder tolerar a maior probabilidade de tais inconsistências, isso poderá ser aceitável.

Mas certamente você não deve jogar todas as perguntas na esperança de que seja um botão "turbo" mágico. Além da maior probabilidade de encontrar resultados anômalos nesse nível de isolamento ou de nenhum resultado (erro "Não foi possível continuar a varredura com o NOLOCK devido ao movimento dos dados"), existem casos em que o desempenho nolock pode ser muito pior .

Martin Smith
fonte
3
+1 - Usamos muito porque nossas tabelas de produção nunca são modificadas.
JNK
@JNK O que você quer dizer com nunca é modificado?
Kuberchaun
4
Martin, eu sugeriria palavras um pouco diferentes: "sob valores confirmados de leitura podem ser perdidos e lidos mais de uma vez". Podemos recuperar uma linha mais de duas vezes em alguns casos exóticos.
AK
@ StarShip3000 Os dados que implementam a produção é basicamente somente leitura para os usuários finais, de modo a maioria de seus pontos de vista têm dicas NOLOCK
JNK
11

Seus clientes toleram resultados inconsistentes nos relatórios? Se a resposta for não, você não deve usar o NOLOCK - pode obter resultados incorretos com a simultaneidade. Escrevi alguns exemplos aqui , aqui e aqui . Esses exemplos mostram resultados inconsistentes em READ COMMITTED e REPEATABLE READ, mas você pode ajustá-los e obter resultados errados com o NOLOCK também.

AK
fonte
A maioria dos relatórios criados não é executada com dados atuais. A maioria dos clientes está executando relatórios são dados de ontem. Sua resposta mudaria se fosse esse o caso?
precisa saber é o seguinte
8

A maioria dos relatórios criados não é executada com dados atuais. A maioria dos clientes está executando relatórios são dados de ontem. Sua resposta mudaria se fosse esse o caso?

Se for esse o caso, você tem mais uma opção possível: em
vez de executar suas consultas no banco de dados de produção e mexer com bloqueios NOLOCK, você pode executar seus relatórios a partir de uma cópia do banco de dados de produção.

Você pode configurá-lo para que seja restaurado automaticamente a partir de um backup todas as noites .
Aparentemente, seus relatórios estão sendo executados em servidores nos sites dos clientes, então não sei se a configuração seria uma solução viável para você.
(mas, novamente ... eles devem ter backups de qualquer maneira, então tudo que você precisa é de algum espaço no servidor para restaurá-los)

Sou desenvolvedor interno, portanto, isso é mais fácil para mim, porque tenho controle total sobre os servidores e bancos de dados.

Você pode fazer isso pelo menos para os relatórios que precisam apenas de dados de ontem e anteriores. Talvez alguns relatórios precisem permanecer no banco de dados de produção, mas pelo menos você move parte da carga para outro banco de dados (ou, melhor ainda, para outro servidor).

Também tenho a mesma situação no trabalho:
estamos usando uma cópia do banco de dados de produção como esta para quase todo o material de relatórios, mas há algumas consultas que exigem os dados de hoje.

Christian Specht
fonte
Eu gosto da sua resposta e funcionaria - se eu tivesse controle total - o que eu não tinha. Muitas vezes, não tenho controle total e não consigo criar índices. Tenho sorte se posso executar / exibir planos de execução.
DataGirl