Explicação solicitada para DELETE lento com o SQL Server

8

Gostaria de obter algumas informações / raciocínios adicionais sobre o comportamento de exclusão do SQL Server. Temos um banco de dados bastante grande com mais de 1800 GB.

Existem algumas tabelas muito rasas (apenas algumas colunas inteiras) com muitos milhões de linhas. Quando excluímos 10.000s de linhas dessas tabelas rasas, as consultas de exclusão geralmente são bastante rápidas (no máximo alguns segundos).

Também temos uma tabela com um campo do tipo que imagearmazena imagens com média de 100 KB. Quando excluímos apenas alguns milhares de linhas desta tabela, leva mais de um minuto.

Embora a diferença seja clara (muito mais tamanho de dados é excluído), estou ansioso para saber mais sobre o que acontece no SQL Server. Para que eu possa entender melhor, o último exclui ser muito mais lento.

Alguém por favor pode lançar alguma luz?

marc_s
fonte
Há um livro sobre as instruções internas do SQL Server, se você estiver interessado nesse tipo de coisa e quiser ouvir as pessoas próximas à fonte.
stakx
Minha suspeita seria que as exclusões da imagem gerassem muitas IO aleatórias, ou elas bloqueiam alguma coisa. Excluir algumas 1000 linhas não resultará em um minuto de uso completo da CPU.
usr

Respostas:

10

muito mais tamanho de dados é excluído

A exclusão de um imageblob de 100 KB não é, na verdade, uma operação de tamanho de dados. O blob é desalocado, não excluído e não há log de imagem completa. Você pode facilmente testar isso:

create database blob
go

use blob
go

create table t (id int not null identity(1,1), blob image)
go

insert into t (blob) values (
  replicate(
    cast(0x000102030405060708090a0b0c0d0e0f as varbinary(max)), 
    100*1024/16))
go 10

alter database blob set recovery full
go

backup database blob to disk='nul:'
go

delete from t where id = 3
go

select * from fn_dblog(null, null)
go

Os registros de log que você verá serão algo como:

00000026:0000008e:0001  LOP_BEGIN_XACT  LCX_NULL    0000:00000304   0x0000  76  124
00000026:0000008e:0002  LOP_LOCK_XACT   LCX_NULL    0000:00000304   0x0000  24  56
00000026:0000008e:0003  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0004  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0005  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0006  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0007  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0008  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0009  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:000a  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:000b  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:000c  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
...    
00000026:0000008e:0022  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0023  LOP_DELETE_ROWS LCX_TEXT_MIX    0000:00000304   0x0000  62  172
00000026:0000008e:0024  LOP_DELETE_ROWS LCX_HEAP    0000:00000304   0x0000  62  120
00000026:0000008e:0025  LOP_COMMIT_XACT LCX_NULL    0000:00000304   0x0000  80  84

Como você pode ver, não há registro 'DELETE' com +102400 bytes de dados para a linha que contém a imagecoluna. Existem várias desalocações (a operação PFS / IAM / GAM) e uma simples exclusão de linha (no meu caso, heap seria muito semelhante para o B-Tree se eu tivesse lembrado de declarar o ID como PK ...). Para obter mais detalhes, consulte Como ler e interpretar o log do SQL Server .

O que deixa em aberto a pergunta original: por que uma exclusão é mais lenta que a outra? Eu recomendo que você leia Como analisar o desempenho do SQL Server . Siga a metodologia descrita para capturar as esperas de uma declaração específica e ver qual é a causa. Consulte Analisando a execução de consultas individuais , especialmente a parte sobre Analisando os tempos de espera da execução de consultas individuais. Somente depois que você medir, poderemos responder ao enigma. pode haver muitos fatores: mais bloqueios devido a leituras simultâneas na tabela de blob, falta de índices para localizar as linhas candidatas a DELETE em uma tabela, aciona a execução etc. etc. A metodologia vinculada ajudará você a identificar a causa.

Remus Rusanu
fonte