Erläuterung für langsames LÖSCHEN mit SQL Server angefordert

8

Ich möchte einige zusätzliche Einblicke / Gründe für das Löschverhalten von SQL Server erhalten. Wir haben eine ziemlich große Datenbank von über 1800 GB.

Darin befinden sich einige sehr flache Tabellen (nur wenige ganzzahlige Spalten) mit vielen Millionen Zeilen. Wenn wir 10.000 Zeilen aus diesen flachen Tabellen löschen, sind die Löschabfragen im Allgemeinen recht schnell (höchstens eine Handvoll Sekunden).

Wir haben auch eine Tabelle mit einem Feld vom Typ, in dem imageBilder mit einer durchschnittlichen Größe von 100 KB gespeichert sind. Wenn wir nur einige tausend Zeilen aus dieser Tabelle löschen, dauert es weit über eine Minute.

Obwohl der Unterschied klar ist (viel mehr Daten werden gelöscht), bin ich gespannt darauf, mehr darüber zu erfahren, was in SQL Server passiert. Damit ich besser verstehen kann, löscht letzteres so viel langsamer.

Kann jemand bitte etwas Licht ins Dunkel bringen?

marc_s
quelle
Es gibt ein Buch über SQL Server-Interna, wenn Sie an solchen Dingen interessiert sind und von denen hören möchten, die sich in der Nähe der Quelle befinden.
Stakx
Mein Verdacht wäre, dass das Löschen des Bildes viele zufällige E / A-Vorgänge erzeugt oder etwas blockiert. Das Löschen einiger 1000 Zeilen führt in keiner Weise zu einer Minute voller CPU-Auslastung.
usr

Antworten:

10

In Bezug auf die Datengröße werden viel mehr Daten gelöscht

Das Löschen eines 100-KB- imageBlobs ist eigentlich keine Operation mit Datengröße. Der Blob wird freigegeben, nicht gelöscht, und es erfolgt keine Vollbildprotokollierung. Sie können dies leicht testen:

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

Die Protokolldatensätze, die Sie sehen, sehen wie folgt aus:

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

Wie Sie sehen können, gibt es keinen 'DELETE'-Datensatz mit +102400 Datenbytes für die Zeile, die die imageSpalte enthält. Es gibt eine Reihe von Freigaben (die PFS / IAM / GAM-Operation) und eine einfache Zeilenlöschung (Heap würde in meinem Fall für B-Tree sehr ähnlich aussehen, wenn ich daran gedacht hätte, ID als PK zu deklarieren ...). Weitere Informationen finden Sie unter Lesen und Interpretieren des SQL Server-Protokolls .

Was die ursprüngliche Frage offen lässt: Warum ist ein Löschvorgang langsamer als der andere? Ich empfehle Ihnen , die Analyse der SQL Server-Leistung zu lesen . Befolgen Sie die beschriebene Methode, um die Wartezeiten für eine bestimmte Anweisung zu erfassen und die Ursache zu ermitteln. Siehe Analysieren der Ausführung einzelner Abfragen , insbesondere den Teil Analysieren der Wartezeiten für die Ausführung einzelner Abfragen. Erst nachdem Sie gemessen haben, können wir das Rätsel beantworten. Es kann viele Faktoren geben: Mehr Blockierung aufgrund gleichzeitiger Lesevorgänge in der Blob-Tabelle, fehlende Indizes zum Auffinden der DELETE-Kandidatenzeilen in einer Tabelle, Ausführen von Triggern usw. usw. Die verknüpfte Methode hilft Ihnen dabei, die Ursache zu ermitteln.

Remus Rusanu
quelle