Estou no negócio de criar sites e aplicativos que não são de missão crítica -> por exemplo. software bancário, voo espacial, aplicativo de monitoramento de terapia intensiva etc. Você entendeu a idéia.
Então, com esse enorme aviso, é ruim usar a dica NOLOCK em alguma instrução SQL? Alguns anos atrás, foi sugerido por um colega Administrador Sql que eu deveria usar o NOLOCK se estiver satisfeito com uma "leitura suja", o que me proporcionará um pouco mais de desempenho do meu sistema, pois cada leitura não bloqueia o mesa / linha / o que for.
Também me disseram que é uma ótima solução se eu estiver enfrentando impasses. Então, comecei a seguir esse pensamento por alguns anos até que um guru do Sql estivesse 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 da explicação dele era 'é uma solução de band-aid para um problema mais sério .. especialmente se você estiver enfrentando um impasse. Como tal, corrija a raiz do problema '.
Recentemente, pesquisei no Google e me deparei com este post .
Então, alguns sql db guru sensei podem me esclarecer?
fonte
Respostas:
Com a dica NOLOCK, o nível de isolamento da transação para a
SELECT
instrução éREAD UNCOMMITTED
. Isso significa que a consulta pode ver dados sujos e inconsistentes.Não é uma boa ideia aplicar-se como regra. Mesmo que esse comportamento de leitura suja seja bom para o seu aplicativo baseado na Web de missão crítica, uma verificação NOLOCK pode causar um erro 601 que encerrará a consulta devido à movimentação de dados como resultado da falta de proteção de bloqueio.
Sugiro a leitura de Quando o isolamento de instantâneo ajuda e quando dói - o MSDN recomenda o uso do INSTANTÂNEO LIDO COMPRIDO, em vez do INSTANTÂNEO, na maioria das circunstâncias.
fonte
Antes de trabalhar no Stack Overflow, eu era contra
NOLOCK
no princípio de que você poderia executar umaSELECT
comNOLOCK
e voltar resultados com os dados que podem estar fora de data ou inconsistente. Um fator a se pensar é 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 conflitos, a menos que você use um modo de banco de dados comoREAD COMMITED SNAPSHOT
.Desde então, mudei de perspectiva sobre o uso de
NOLOCK
depois de testemunhar como ele pode melhorar oSELECT
desempenho e eliminar os impasses em um SQL Server carregado em massa. Há momentos em que você pode não se importar se seus dados não são exatamente 100% confirmados e você precisa de resultados rapidamente, mesmo que estejam desatualizados.Faça uma pergunta a si mesmo ao pensar em usar
NOLOCK
:Se a resposta for não, use
NOLOCK
para melhorar o desempenho.Acabei de realizar uma pesquisa rápida pelo
NOLOCK
palavra chave na base de código do Stack Overflow e encontrei 138 instâncias, por isso a usamos em alguns lugares.fonte
NOLOCK
. Isso significa que eu tenho que rebaixar sua resposta. Desculpe.SELECT
, a leitura somente de um índice de cobertura, pode causar um conflito. SPID 1) inicia um aSELECT
partir do índice de cobertura. SPID 2) Inicie umaUPDATE
tabela. A atualização passa para a atualização do índice de cobertura.UPDATE
atinge um intervalo de índice bloqueado peloSELECT
e fica bloqueado. O SPID 1) ainda procura pelo índice de cobertura, encontra um intervalo bloqueado peloUPDATE
e fica bloqueado. PRAZO . Nada pode resolver esse impasse (exceto captura de erro SQL Server 1205, e automaticamente tentar novamente, ou usandoNOLOCK
)Se você não se importa com leituras sujas (ou seja, em uma situação predominantemente READ), tudo
NOLOCK
bem.MAS , lembre-se de que a maioria dos problemas de bloqueio ocorre devido à falta de índices 'corretos' para sua carga de trabalho de consulta (supondo que o hardware esteja pronto para a tarefa).
E a explicação do guru estava correta. Geralmente é uma solução de band-aid para um problema mais sério.
Edit : Definitivamente, não estou sugerindo que o NOLOCK deva ser usado. Acho que deveria ter deixado isso obviamente claro. (Eu só o usaria em circunstâncias extremas em que havia analisado que estava tudo bem). Como exemplo, um tempo atrás, trabalhei em alguns TSQL que foram polvilhados com o NOLOCK para tentar aliviar os problemas de bloqueio. Removai todos eles, implementei os índices corretos e TODOS os impasses desapareceram.
fonte
Duvido que fosse um "guru" que tivesse alguma experiência em tráfego intenso ...
Os sites geralmente estão "sujos" quando a pessoa está 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 falam sobre leituras sujas sendo tão não-não.
Dito isto, se você tiver várias camadas construídas em suas seleções, poderá criar uma redundância perigosa. Se você estiver lidando com cenários financeiros ou de status, precisará não apenas de leitura / gravação de dados transacionais, mas também de uma solução de concorrência adequada (algo que a maioria dos "gurus" não se incomoda).
Por outro lado, se você tem uma pesquisa avançada de produtos 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 de alguns usuários simultâneos (fenomenal quantos "especialistas" não têm), é ridículo engarrafar todos os outros processos por trás dele.
Saiba o que isso significa e use-o quando apropriado. Atualmente, seu banco de dados quase sempre será o principal gargalo da sua garrafa, e ser inteligente sobre o uso do NOLOCK pode economizar milhares em infraestrutura.
EDIT: Não são apenas os impasses que ajudam, é também o quanto você fará todo mundo esperar até terminar, ou vice-versa.
Usando a dica NOLOCK no EF4?
fonte
Nenhuma das respostas está errada, por mais confuso que seja.
fonte
Como desenvolvedor profissional, eu diria que depende. Mas eu definitivamente sigo os conselhos dos GATS e OMG Ponies. Saiba o que você está fazendo, saiba quando ajuda e quando dói e
leia dicas e outras idéias ruins
o que pode fazer você entender o servidor sql mais profundamente. Geralmente, sigo a regra de que as dicas do SQL são MAL, mas, infelizmente, eu as uso de vez em quando quando estou cansado de forçar o SQL Server a fazer coisas ... Mas esses são casos raros.
Lucas
fonte
Quando o suporte ao aplicativo queria responder a consultas ad-hock do servidor de produção usando SSMS (que não eram atendidos por meio de relatórios), solicitei que eles usassem o nolock. Dessa forma, o negócio 'principal' não é afetado.
fonte
Concordo com alguns comentários sobre a dica do NOLOCK e, especialmente, com aqueles que dizem "use-a quando for apropriado". Se o aplicativo tiver sido mal escrito e estiver usando uma maneira inadequada de simultaneidade - isso pode causar o aumento do bloqueio. A tabela altamente transacional também fica bloqueada o tempo todo devido à sua natureza. Ter uma boa cobertura de índice não ajudará na recuperação dos dados, mas configurar ISOLATION LEVEL como READ UNCOMMITTED. Também acredito que o uso da dica NOLOCK é seguro em muitos casos quando a natureza das alterações é previsível. Por exemplo - na fabricação quando trabalhos com viajantes estão passando por processos diferentes com muitas inserções de medidas, é possível executar com segurança consultas no trabalho final com a dica NOLOCK e, dessa forma, evitar colisão com outras sessões que colocam bloqueios PROMOTED ou EXCLUSIVO na mesa /página. Os dados que você acessa nesse 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
fonte
Acredito que praticamente nunca é correto usar o nolock.
Se você estiver lendo uma única linha, o índice correto significa que você não precisará do NOLOCK, pois as ações individuais da linha são concluídas rapidamente.
Se você estiver lendo muitas linhas para algo que não seja exibição temporária e se preocupa em poder repetir o resultado ou defender pelo número produzido, o NOLOCK não é apropriado.
NOLOCK é uma marca substituta para "não me importo se esta resposta contiver linhas duplicadas, linhas excluídas ou linhas que nunca foram inseridas para começar por causa da reversão"
Erros possíveis sob NOLOCK:
Qualquer ação que possa causar uma divisão de página enquanto a seleção noLock estiver em execução pode causar essas coisas. Quase qualquer ação (mesmo uma exclusão) pode causar uma divisão de página.
Portanto: se você "sabe" que a linha não será alterada enquanto estiver em execução, não use 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 se preocupa com a precisão, não use nolock.
Se você estiver considerando NOLOCK por causa de conflitos, examine a estrutura do plano de consulta para verificações inesperadas da tabela, rastreie os conflitos e veja por que eles ocorrem. NOLOCK em torno de gravações pode significar que as consultas que antes estavam em um impasse potencialmente escreveriam a resposta errada.
fonte
As melhores soluções, quando possível, são:
O nível de isolamento de transação INSTANTÂNEO foi criado porque a MS estava perdendo vendas para a Oracle. O Oracle usa desfazer / refazer logs para evitar esse problema. O Postgres usa MVCC. No futuro, o Heckaton da MS usará o MVCC, mas faltam anos para estar pronto para a produção.
fonte
O NOLOCK é frequentemente explorado como uma maneira mágica de acelerar as leituras do banco de dados, mas tento evitar usá-lo sempre que possível.
O conjunto de resultados pode conter linhas que ainda não foram confirmadas, que geralmente são revertidas posteriormente.
Um erro ou conjunto de resultados pode estar vazio, estar faltando linhas ou exibir a mesma linha várias vezes.
Isso ocorre porque outras transações estão movendo dados ao mesmo tempo em que você os lê.
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.
fonte
Na vida real, onde você encontra sistemas já escritos e adiciona índices a tabelas e depois diminui drasticamente o carregamento de dados de uma tabela de dados 14gig, às vezes você é forçado a usar o WITH NOLOCK em seus relatórios e a análise de final de mês para que as funções agregadas (soma , contagem, etc.) não fazem linha, página, bloqueio de tabela e impedem o desempenho geral. É fácil dizer que em um novo sistema nunca use WITH NOLOCK e use índices - mas a adição de índices reduz severamente o carregamento de dados e, quando me dizem isso, altere a base de código para excluir índices, depois carregue em massa e recrie os índices - o que está tudo muito bem, se você estiver desenvolvendo um novo sistema. Mas não quando você já possui um sistema.
fonte