Explication demandée pour la suppression lente avec SQL Server

8

Je voudrais obtenir des informations / un raisonnement supplémentaires pour le comportement de suppression de SQL Server. Nous avons une base de données assez volumineuse de plus de 1800 Go.

Il y a des tables très peu profondes (seulement quelques colonnes entières) avec plusieurs millions de lignes. Lorsque nous supprimons 10 000 lignes de ces tables peu profondes, les requêtes de suppression sont généralement assez rapides (tout au plus quelques secondes).

Nous avons également un tableau avec un champ de type imagestockant des images d'une moyenne de 100 Ko. Lorsque nous supprimons seulement quelques milliers de lignes de ce tableau, cela prend bien plus d'une minute.

Bien que la différence soit claire (beaucoup plus de données sont supprimées), je suis impatient d'en savoir plus sur ce qui se passe dans SQL Server. Pour que je puisse mieux comprendre que ces dernières suppressions sont tellement plus lentes.

Quelqu'un peut-il faire la lumière?

marc_s
la source
Il existe un livre sur les composants internes de SQL Server si vous êtes intéressé par ce genre de chose et que vous souhaitez entendre ceux qui sont proches de la source.
stakx
Je soupçonne que les suppressions d'images génèrent beaucoup d'E / S aléatoires ou bloquent quelque chose. La suppression de quelques 1 000 lignes n'entraînera en aucune façon une minute d'utilisation complète du processeur.
usr

Réponses:

10

beaucoup plus de données sont supprimées

La suppression d'un objet imageblob de 100 Ko n'est en fait pas une opération de taille de données. Le blob est désalloué, non supprimé et il n'y a pas de journalisation d'image complète. Vous pouvez facilement tester cela:

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

Les enregistrements de journal que vous verrez seront quelque chose comme:

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

Comme vous pouvez le voir, il n'y a pas d'enregistrement 'DELETE' avec +102400 octets de données pour la ligne contenant la imagecolonne. Il y a un tas de désallocations (l'opération PFS / IAM / GAM) et une simple suppression de ligne (le tas dans mon cas, aurait l'air très similaire pour B-Tree si je me souvenais de déclarer ID comme PK ...). Pour plus de détails, consultez Comment lire et interpréter le journal SQL Server .

Ce qui laisse ouverte la question initiale: pourquoi une suppression est-elle plus lente que l'autre? Je vous recommande de lire Comment analyser les performances de SQL Server . Suivez la méthodologie décrite pour capturer les attentes pour une déclaration spécifique et voir quelle en est la cause. Voir Analyse de l'exécution de requêtes individuelles , en particulier la partie sur l'analyse des temps d'attente pour l'exécution de requêtes individuelles. Ce n'est qu'après avoir mesuré que nous pourrons répondre à l'énigme. il peut y avoir de nombreux facteurs: plus de blocage en raison de lectures simultanées sur la table d'objets blob, d'index manquants pour localiser les lignes candidates DELETE sur une table, de déclencheurs en cours d'exécution, etc. La méthodologie liée vous aidera à identifier la cause.

Remus Rusanu
la source