Pergunta

Estou no negócio de fazer site e aplicativos que são não missão crítica -> por exemplo. Software bancário, voo espacial, aplicativo de monitoramento de terapia intensiva, etc. Você obtém a ideia.

Então, com esse aviso maciço, isso é ruim usando a dica de Nolock em alguma declaração SQL? Alguns anos atrás, foi sugerido por um colega administrador de SQL que eu deveria usar Nolock se estiver feliz com uma "leitura suja", que me dará um pouco mais de desempenho do meu sistema, porque cada leitura não trava o Tabela/linha/o que for.

Também me disseram que é uma ótima solução se estou experimentando trancas mortas. Então, comecei a seguir esse pensamento por alguns anos até que um Guru do SQL estava me ajudando com algum código aleatório e notei todos os Nolocks no meu código SQL. Eu fui educadamente repreendido e ele tentou me explicar (por que não é uma coisa boa) e eu meio que me perdi. Eu senti que a essência de sua explicação era 'é uma solução de band-aid para um problema mais sério. Especialmente se você estiver enfrentando terraço. Como tal, corrija a raiz do problema '.

Eu fiz alguns pesquisando no Google recentemente sobre isso e me deparei esta postagem.

Então, alguns sql db guru sensei podem me esclarecer?

Foi útil?

Solução

Com a dica de Nolock, o nível de isolamento da transação para o SELECT declaração é READ UNCOMMITTED. Isso significa que a consulta pode ver dados sujos e inconsistentes.

Esta não é uma boa ideia aplicar como regra. Mesmo que esse comportamento sujo de leitura seja bom para o seu aplicativo missionário baseado na Web, uma varredura NOLOCK pode causar um erro 601 que encerrará a consulta devido ao movimento de dados como resultado da falta de proteção de travamento.

Eu sugiro ler Quando o isolamento do instantâneo ajuda e quando dói - O MSDN recomenda o uso de instantâneos de leitura comprometida em vez de instantâneos na maioria das circunstâncias.

Outras dicas

Antes de trabalhar no transbordamento da pilha, eu era contra NOLOCK no diretor que você poderia potencialmente realizar um SELECT com NOLOCK e recupere os resultados com dados que podem estar desatualizados ou inconsistentes. Um fator a ser pensado é quantos registros podem ser inseridos/atualizados ao mesmo tempo em que outro processo pode estar selecionando dados da mesma tabela. Se isso acontecer muito, há uma alta probabilidade de impasse, a menos que você use um modo de banco de dados, como READ COMMITED SNAPSHOT.

Desde então, mudei minha perspectiva sobre o uso de NOLOCK Depois de testemunhar como isso pode melhorar SELECT Desempenho, bem como eliminar os deadlocks em um servidor SQL massivamente carregado. Há momentos em que você pode não se importar que seus dados não estejam exatamente 100% comprometidos e você precisa de resultados de volta rapidamente, mesmo que eles estejam desatualizados.

Faça a si mesmo uma pergunta ao pensar em usar NOLOCK:

Minha consulta inclui uma tabela que tem um grande número de INSERT/UPDATE Comandos e eu me importo se os dados retornados de uma consulta podem estar perdendo essas alterações em um determinado momento?

Se a resposta for não, então use NOLOCK para melhorar o desempenho.


Acabei de fazer uma pesquisa rápida pelo NOLOCK Palavra -chave dentro da base de código para o excesso de pilha e encontrou 138 instâncias, por isso o usamos em alguns lugares.

Se você não se importa com leituras sujas (ou seja, em uma situação predominantemente lida), então NOLOCK está bem.

MAS, Esteja ciente de que a maioria dos problemas de bloqueio se deve a não ter os índices 'corretos' para sua carga de trabalho de consulta (assumindo que o hardware esteja à altura da tarefa).

E a explicação do Guru estava correta. Geralmente é uma solução de band-aid para um problema mais sério.

Editar: Definitivamente, não estou sugerindo que Nolock seja usado. Acho que deveria ter deixado isso obviamente claro. (Eu só o usaria, em circunstâncias extremas em que analisei que estava tudo bem). Como exemplo, há algum tempo, trabalhei em alguns TSQL que haviam sido polvilhados com Nolock para tentar aliviar os problemas de travamento. Eu removi todos eles, implementei os índices corretos e todos os impasse foram embora.

Duvide que foi um "guru" que teve alguma experiência em tráfego alto ...

Os sites geralmente são "sujos" quando a pessoa estiver visualizando a página completamente carregada. Considere um formulário que carrega do banco de dados e salva os dados editados? É idiota a maneira como as pessoas fazem sobre leituras sujas sendo um não não.

Dito isto, se você tiver várias camadas construindo em suas seleções, poderá estar construindo uma redundância perigosa. Se você estiver lidando com cenários de dinheiro ou status, não apenas precisará de dados transacionais de leitura/gravação, mas também uma solução de simultaneidade adequada (algo que a maioria dos "gurus" não se preocupa).

Por outro lado, se você tiver uma pesquisa avançada de produto para um site (ou seja, algo que provavelmente não será armazenado em cache e é um pouco intensivo) e você já construiu um site com mais do que alguns usuários simultâneos (fenominais quantos "Especialistas" não), é ridículo engarrafar o pescoço todos os outros processos por trás dele.

Saiba o que isso significa e use -o quando apropriado. Seu banco de dados quase sempre será o seu pescoço de garrafa principal hoje em dia e ser inteligente ao usar o Nolock pode economizar milhares em infraestrutura.

EDITAR: Não são apenas os deadlocks que ajudam, também é o quanto você vai fazer com que todos os outros esperem até terminar, ou vice -versa.

Usando a dica de nolock no EF4?

Nenhuma das respostas está errada, por mais confusa que seja.

  • Ao consultar valores únicos/linhas, é sempre Más práticas para usar o Nolock - você provavelmente nunca deseja exibir informações incorretas ou talvez até tomar qualquer ação sobre dados incorretos.
  • Ao exibir informações estatísticas aproximadas, o Nolock pode ser muito útil. Tome assim como um exemplo: seria um absurdo pegar fechaduras para ler o exato Número de visualizações de uma pergunta ou o número exato de perguntas para uma tag. Ninguém se importa se você declarar incorretamente 3360 perguntas marcadas com o "SQL-Server" agora e, devido a uma reversão de transações, 3359 questionam um segundo depois.

Como desenvolvedor profissional, eu diria que isso depende. Mas eu definitivamente sigo conselhos de Gats e OMG Ponies. Saiba o que você está fazendo, saiba quando ajuda e quando dói e

ler dicas e outras idéias ruins

O que pode fazer você entender o servidor SQL mais profundo. Geralmente, sigo a regra de que as dicas do SQL são más, mas infelizmente as uso de vez em quando quando fico farto de forçar o SQL Server fazer as coisas ... mas esses são casos raros.

Lucas

Quando o App-support queria responder às consultas de anúncios do servidor de produção usando o SSMS (que não eram atendidas via relatórios), solicitei que eles usassem o Nolock. Dessa forma, o negócio 'principal' não é afetado.

Concordo com alguns comentários sobre a dica de Nolock e, especialmente, com aqueles que dizem "use -o quando for apropriado". Se o aplicativo escrito mal e estiver usando uma maneira inadequada de simultaneidade - isso pode causar a escalada de bloqueio. A tabela altamente transacional também está ficando bloqueada o tempo todo devido à sua natureza. Ter uma boa cobertura de índice não ajudará a recuperar os dados, mas definir o nível de isolamento para ler não confirmado. Também acredito que o uso da dica de Nolock é seguro em muitos casos em que a natureza das mudanças é previsível. Por exemplo - na fabricação quando empregos com viajantes estão passando por diferentes processos com muitas inserções de medições, você pode executar com segurança a consulta contra o trabalho final com a dica de Nolock e, dessa maneira /página. Os dados que você acessa neste caso são estáticos, mas podem residir em uma tabela muito transacional com centenas de milhões de registros e milhares de atualizações/inserções por minuto. Felicidades

Eu acredito que praticamente nunca é correto usar o Nolock.

Se você estiver lendo uma única linha, o índice correto significa que você não precisará de Nolock à medida que as ações individuais da linha são concluídas rapidamente.

Se você estiver lendo muitas linhas para qualquer outra coisa que senão a exibição temporária e se preocupe em poder repetir o resultado ou defender pelo número produzido, o Nolock não será apropriado.

Nolock é uma etiqueta substituta para "Eu não me importo se essa resposta contém linhas duplicadas, linhas que são excluídas ou linhas que nunca foram inseridas para começar por causa da reversão"

Erros que são possíveis sob Nolock:

  • Linhas que correspondem não são devolvidas.
  • Linhas únicas são retornadas várias vezes (incluindo várias instâncias da mesma chave primária)
  • Linhas que não correspondem são devolvidas.

Qualquer ação que possa causar uma divisão de página enquanto o Nolock Select está em execução pode fazer com que essas coisas ocorram. Quase qualquer ação (mesmo uma exclusão) pode causar uma divisão de página.

Portanto: se você "souber" que a linha não será alterada enquanto estiver em execução, não use o Nolock, pois um índice permitirá uma recuperação eficiente.

Se você suspeitar que a linha pode mudar enquanto a consulta está em execução e você se preocupa com precisão, não use o Nolock.

Se você está pensando em Nolock por causa de impasse, examine a estrutura do plano de consulta para verificações inesperadas da tabela, rastreie os impasse e veja por que eles ocorrem. Nolock, em torno, as gravações podem significar que as consultas que anteriormente foram implementadas potencialmente escreverão a resposta errada.

As melhores soluções, quando possível são:

  • Replique seus dados (usando log-replicação) em um banco de dados de relatórios.
  • Use SAN Snapshots e monte uma versão consistente do banco de dados
  • Use um banco de dados que tenha um melhor nível de isolamento de transação fundamental

O nível de isolamento de transações instantâneas foi criado porque a MS estava perdendo vendas para o Oracle. O Oracle usa logs de desfazer/refazer para evitar esse problema. O PostGres usa o MVCC. No futuro, Heckaton do MS usará o MVCC, mas isso está fora de estar pronto para a produção.

Nolock é frequentemente explorado como uma maneira mágica de acelerar as leituras do banco de dados, mas tento evitar usá -lo para o que é possível.

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

Um erro ou conjunto de resultados pode estar vazio, faltando linhas ou exibir a mesma linha várias vezes.

Isso ocorre porque outras transações estão movendo dados ao mesmo tempo que você está lendo.

A leitura comprometida 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.

Na vida real, onde você encontra sistemas já escritos e adicionando índices às tabelas, então diminui drasticamente o carregamento de dados de uma tabela de dados 14gig, você é forçado a ser usado com Nolock em seus relatórios e no final do mês, para que as funções agregadas (soma , contagem etc.) não faça linha, página, bloqueio de tabela e determine o desempenho geral. Fácil de dizer em um novo sistema nunca use com o Nolock e use índices - mas a adição de índices rebaixa gravemente o carregamento de dados e, quando me disseram, bem, altere a base de código para excluir índices e depois recriar os índices - que está tudo bem, se você está desenvolvendo um novo sistema. Mas não quando você já tem um sistema no lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top