Tenho uma tabela que é constantemente atualizada por alguns scripts. Os scripts estão adicionando novos valores e alterando tuplas, mas nunca excluindo nenhuma tupla.
Preciso executar algumas consultas, que usam todas as linhas da tabela (cerca de 2 milhões no momento) para junção. O problema é que os scripts bloqueiam a tabela de uma forma, que minhas instruções select são bloqueadas e executadas muito lentamente (compare 16 minutos versus alguns segundos se estiver executando sem nenhum script em segundo plano).
É possível bloquear a tabela de forma que eu leia um instantâneo atual e não me importe com as alterações? Para a maioria dos aplicativos, é suficiente permitir que entradas fantasmas estejam presentes (os dados são alterados/adicionados enquanto a consulta selecionada estava em execução). Não é necessário na maioria dos casos bloquear a tabela inteira, mas sim usar um bloqueio de coluna (que eu acho que não funcionará no meu MS SQL Server 2005)
Parece que você deseja considerar
READ COMMITTED SNAPSHOT ISOLATION
, que usa tempdb para fornecer uma versão pontual dos dados e impede que os escritores bloqueiem os leitores e vice-versa (desde que esteja tudo bem que os leitores não vejam a versão mais atual da linha ). Com uma tabela tão grande e tendo tanto impacto por operações de gravação simultâneas, o impacto no tempdb pode ser enorme e não há como prever isso, então você precisará testá-lo.Kendra Little tem uma ótima postagem de introdução do lado da administração aqui:
E Paul White detalha o que acontece no nível da consulta aqui, em sua série sobre ACID e os vários níveis de isolamento de transação no SQL Server:
Documentação oficial que você deseja revisar, especialmente para entender como funciona e as limitações envolvidas: