Explicación solicitada para DELETE lento con SQL Server

8

Me gustaría obtener algunas ideas / razonamientos adicionales para el comportamiento de eliminación de SQL Server. Tenemos una base de datos bastante grande de más de 1800 GB.

Hay algunas tablas muy poco profundas (solo unas pocas columnas enteras) con muchos millones de filas. Cuando eliminamos 10,000s de filas de estas tablas poco profundas, las consultas de eliminación son generalmente bastante rápidas (a lo sumo unos pocos segundos).

También tenemos una tabla con un campo de tipo que imagealmacena imágenes con un promedio de 100 KB. Cuando eliminamos solo unos pocos miles de filas de esta tabla, lleva más de un minuto.

Aunque la diferencia es clara (se eliminan muchos más datos en cuanto al tamaño), estoy ansioso por aprender más sobre lo que sucede dentro de SQL Server. Para que pueda entender mejor, este último borrado es mucho más lento.

¿Alguien puede arrojar algo de luz?

marc_s
fuente
Hay un libro sobre aspectos internos de SQL Server si está interesado en ese tipo de cosas y desea escuchar a las personas cercanas a la fuente.
stakx
Mi sospecha sería que las eliminaciones de imágenes generan muchos IO aleatorios, o bloquean algo. Eliminar unas 1000 filas no resultará en un minuto de uso total de la CPU de ninguna manera.
Usr

Respuestas:

10

se eliminan muchos más datos en cuanto al tamaño

Eliminar un imageblob de 100 kb en realidad no es una operación de tamaño de datos. El blob se desasigna, no se elimina, y no hay registro de imagen completa. Puedes probar esto fácilmente:

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

Los registros de registro que verá serán 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 puede ver, no hay un registro 'BORRAR' con +102400 bytes de datos para la fila que contiene la imagecolumna. Hay un montón de desasignaciones (la operación PFS / IAM / GAM) y una simple eliminación de fila (montón en mi caso, se vería muy similar para B-Tree si hubiera recordado declarar ID como PK ...). Para obtener más detalles, consulte Cómo leer e interpretar el registro de SQL Server .

Lo que deja abierta la pregunta original: ¿por qué una eliminación es más lenta que la otra? Le recomiendo que lea Cómo analizar el rendimiento de SQL Server . Siga la metodología descrita para capturar las esperas de una declaración específica y ver cuál es la causa. Consulte Análisis de ejecución de consultas individuales , especialmente la parte sobre Análisis de tiempos de espera de ejecución de consultas individuales. Solo después de que hayas medido podremos responder el enigma. Podría haber muchos factores: más bloqueo debido a lecturas concurrentes en la tabla de blobs, índices faltantes para ubicar las filas candidatas de ELIMINAR en una tabla, activadores que se ejecutan, etc. La metodología vinculada le ayudará a identificar la causa.

Remus Rusanu
fuente