Penjelasan yang diminta untuk DELETE lambat dengan SQL Server

8

Saya ingin mendapatkan beberapa wawasan / alasan tambahan untuk perilaku menghapus SQL Server. Kami memiliki database yang cukup besar lebih dari 1800 GB.

Di sana ada beberapa tabel yang sangat dangkal (hanya beberapa kolom integer) dengan jutaan baris. Ketika kami menghapus 10.000 baris dari tabel dangkal ini, pertanyaan penghapusan umumnya cukup cepat (paling banyak beberapa detik).

Kami juga memiliki tabel dengan bidang imagepenyimpanan tipe gambar rata-rata 100 KB. Saat kami menghapus hanya beberapa ribu baris dari tabel ini, dibutuhkan lebih dari satu menit.

Meskipun perbedaannya jelas (lebih banyak ukuran data yang dihapus), saya ingin belajar lebih banyak tentang apa yang terjadi di dalam SQL Server. Sehingga saya bisa lebih mengerti menghapus yang terakhir menjadi jauh lebih lambat.

Adakah yang bisa menjelaskan?

marc_s
sumber
Ada buku tentang SQL Server internal jika Anda tertarik pada hal semacam itu dan ingin mendengar dari mereka yang dekat dengan sumbernya.
stakx
Kecurigaan saya adalah bahwa penghapusan gambar akan menghasilkan banyak IO acak, atau mereka memblokir sesuatu. Menghapus beberapa baris 1000 tidak akan menghasilkan satu menit penggunaan CPU penuh dengan cara apa pun.
usr

Jawaban:

10

lebih banyak ukuran data yang dihapus

Menghapus imagegumpalan 100kb sebenarnya bukan operasi ukuran data. Gumpalan dinonaktifkan, tidak dihapus, dan tidak ada logging gambar penuh. Anda dapat dengan mudah menguji ini:

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

Catatan log yang akan Anda lihat akan menjadi sesuatu di sepanjang baris:

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

Seperti yang Anda lihat tidak ada catatan 'HAPUS' dengan +102400 byte data untuk baris yang berisi imagekolom. Ada banyak deallocations (operasi PFS / IAM / GAM) dan penghapusan baris sederhana (tumpukan dalam kasus saya, akan terlihat sangat mirip untuk B-Tree seandainya saya ingat untuk menyatakan ID sebagai PK ...). Untuk detail lebih lanjut lihat Cara membaca dan menafsirkan log SQL Server .

Yang meninggalkan pertanyaan awal: mengapa satu penghapusan lebih lambat dari yang lain? Saya sarankan Anda membaca Cara menganalisis kinerja SQL Server . Ikuti metodologi yang dijelaskan untuk menangkap menunggu untuk pernyataan tertentu dan melihat apa penyebabnya. Lihat Menganalisis eksekusi permintaan individual , khususnya bagian tentang Menganalisis waktu tunggu eksekusi permintaan individual. Hanya setelah Anda mengukur kami akan dapat menjawab teka-teki itu. mungkin ada banyak faktor: lebih banyak pemblokiran karena pembacaan bersamaan pada tabel blob, indeks yang hilang untuk menemukan baris kandidat DELETE pada satu tabel, pemicu yang berjalan dll. Metodologi yang ditautkan akan membantu Anda menentukan penyebabnya.

Remus Rusanu
sumber