SQL Server 2014 Standard Edition
Temos uma tabela com mais de 100 milhões de linhas.
Precisamos atualizar os valores em algumas colunas.
Fizemos o abaixo, e ele está em execução há 18 horas e fez apenas 17 milhões de linhas. Está ficando cada vez mais lento.
É um servidor razoavelmente quente e sistema de disco (EMC RAID10 e tudo isso). O CREATE INDEX levou cerca de 20 minutos (uma interrupção infeliz que tivemos que tolerar).
Que abordagem podemos usar para passar por isso mais rápido? (on-line fortemente preferido)
CREATE NONCLUSTERED INDEX RECORD_DELETED_INDEX ON [dbo].[huge-table] ( [deleted] ASC, [deletedDate] ASC );
GO
DECLARE @CHUNK_SIZE int
SET @CHUNK_SIZE = 4000 -- to stay under lock escalation threshhold
UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
where deleted is null or deletedDate is null
WHILE @@ROWCOUNT > 0
BEGIN
UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
where deleted is null or deletedDate is null
END
Provavelmente teria sido melhor criar o índice como filtro (ou seja, com uma cláusula WHERE), pois ele ficaria menor à medida que você atualizasse mais registros que seriam filtrados dele:
No entanto, você ainda terá o problema de verificar esse índice toda vez que o loop for executado. Com 100 milhões de linhas na tabela e atualizando 4.000 por iteração, ou seja, 25.000 vezes você está verificando a tabela (ou índice) procurando linhas para atualizar. Seria melhor se você reduzisse o número de vezes que você consultou a tabela.
Por favor, veja minha resposta a uma de suas outras perguntas sobre este projeto para uma configuração que deve tornar este processo muito mais rápido:
servidor sql: atualizando campos em uma tabela enorme em pequenos pedaços: como obter progresso/status?
Nessa resposta, mostro como consultar a tabela grande apenas 100 vezes. Cada vez que ele pega o(s) campo(s)-chave do índice agrupado e os usa para todas as
UPDATE
consultas, para que as atualizações sejam rápidas. E essa configuração também permite obter o progresso atual da operação rapidamente (e sem ter que consultar a tabela!) e cancelar o processo de forma limpa.Deve-se notar que esta pergunta se refere às seguintes perguntas (listadas em ordem cronológica):