HAPUS vs TRUNCATE

35

Saya mencoba untuk mendapatkan pemahaman yang lebih besar tentang perbedaan antara perintah DELETEdan TRUNCATEperintah. Pemahaman saya tentang internal berjalan di sepanjang garis:

DELETE-> mesin basis data menemukan dan menghapus baris dari halaman data yang relevan dan semua halaman indeks di mana baris dimasukkan. Dengan demikian, semakin banyak indeks, semakin lama proses penghapusan.

TRUNCATE -> cukup menghapus semua halaman data tabel secara massal menjadikan ini pilihan yang lebih efisien untuk menghapus isi tabel.

Anggap hal di atas benar (mohon perbaiki saya jika tidak):

  1. Bagaimana berbagai mode pemulihan memengaruhi setiap pernyataan? Jika ada efek sama sekali
  2. Saat menghapus, apakah semua indeks dipindai atau hanya indeks yang barisnya ada? Saya akan menganggap semua indeks dipindai (dan tidak dicari?)
  3. Bagaimana perintah direplikasi? Apakah perintah SQL dikirim dan diproses pada setiap pelanggan? Atau MSSQL sedikit lebih pintar dari itu?
Stuart Blackler
sumber
2
Ada beberapa informasi terkait pada DELETEdan TRUNCATEdalam jawaban atas pertanyaan ini tentang kegunaan TRUNCATE-ing segera sebelum a DROP. Anda juga bisa menggali log sendiri untuk mempelajari efek dari kedua perintah menggunakan teknik yang dijelaskan dalam jawaban ini .
Nick Chammas
1
Jawaban ini menunjukkan internal operasi DELETE dan TRUNCATE. Juga pertanyaan tersebut menunjukkan situasi tertentu di mana TRUNCATE bekerja lebih baik.
孔夫子
5
@ idstam TRUNCATEdapat diputar kembali. Nick membahas hal itu dalam jawabannya terhadap pertanyaan yang ia tautkan .
Mark Storey-Smith
Truncate memerlukan izin "ubah tabel" (dalam arti truncate adalah plug in pengganti untuk dihapus).
crokusek

Jawaban:

58

HAPUS -> mesin database menemukan dan menghapus baris dari halaman data yang relevan dan semua halaman indeks di mana baris dimasukkan. Dengan demikian, semakin banyak indeks, semakin lama proses penghapusan.

Ya, meskipun ada dua opsi di sini. Baris dapat dihapus dari indeks baris demi baris oleh operator yang sama yang melakukan penghapusan tabel dasar. Ini dikenal sebagai paket pembaruan yang sempit (atau per-baris):

Penghapusan per baris

Atau, penghapusan indeks nonclustered dapat dilakukan oleh operator terpisah, satu per indeks nonclustered. Dalam hal ini (dikenal sebagai rencana pembaruan lebar, atau per indeks) set lengkap tindakan disimpan di meja kerja (spool yang diinginkan) sebelum diputar ulang satu kali per indeks, sering secara eksplisit diurutkan berdasarkan kunci indeks nonclustered tertentu untuk mendorong berurutan pola akses.

Penghapusan per indeks

TRUNCATE -> cukup menghapus semua halaman data tabel secara massal menjadikan ini pilihan yang lebih efisien untuk menghapus isi tabel.

Iya nih. TRUNCATE TABLElebih efisien karena sejumlah alasan:

  1. Mungkin diperlukan lebih sedikit kunci. Pemotongan biasanya hanya memerlukan satu kunci modifikasi skema tunggal di tingkat tabel (dan kunci eksklusif pada setiap tingkat yang tidak dapat dialokasikan). Penghapusan mungkin mendapatkan kunci di granularity (baris atau halaman) yang lebih rendah serta kunci eksklusif pada halaman mana pun yang tidak dialokasikan.
  2. Hanya pemotongan yang menjamin bahwa semua halaman dialokasikan dari tabel heap. Penghapusan dapat meninggalkan halaman kosong di tumpukan bahkan jika petunjuk kunci tabel eksklusif ditentukan (misalnya jika tingkat isolasi versi baris diaktifkan untuk database).
  3. Pemotongan selalu dicatat minimal (terlepas dari model pemulihan yang digunakan). Hanya operasi deallokasi halaman yang dicatat dalam log transaksi.
  4. Pemotongan dapat menggunakan drop yang ditangguhkan jika objek 128 ukuran atau lebih besar. Deferred drop berarti pekerjaan deallokasi yang sebenarnya dilakukan secara serempak oleh utas server latar belakang.

Bagaimana berbagai mode pemulihan memengaruhi setiap pernyataan? Apakah ada efeknya?

Penghapusan selalu dicatat sepenuhnya (setiap baris yang dihapus dicatat dalam log transaksi). Ada beberapa perbedaan kecil dalam isi catatan log jika model pemulihan selain dari itu FULL, tetapi ini secara teknis masih log penuh.

Saat menghapus, apakah semua indeks dipindai atau hanya indeks yang barisnya ada? Saya akan menganggap semua indeks dipindai (dan tidak dicari?)

Menghapus baris dalam indeks (menggunakan paket pembaruan sempit atau lebar yang ditunjukkan sebelumnya) selalu merupakan akses dengan kunci (pencarian). Memindai seluruh indeks untuk setiap baris yang dihapus akan sangat tidak efisien. Mari kita lihat kembali pada rencana pembaruan per-indeks yang ditunjukkan sebelumnya:

Rencana luas 2

Rencana pelaksanaan adalah pipa yang digerakkan oleh permintaan: operator induk (ke kiri) mendorong operator anak untuk melakukan pekerjaan dengan meminta satu baris pada satu waktu dari mereka. Operator Sortir memblokir (mereka harus menggunakan seluruh input mereka sebelum menghasilkan baris yang diurutkan pertama), tetapi mereka masih digerakkan oleh orang tua mereka (Penghapusan Indeks) yang meminta baris pertama. Penghapusan Indeks menarik satu baris sekaligus dari Sort yang selesai, memperbarui indeks target nonclustered untuk setiap baris.

Dalam paket pembaruan yang luas, Anda akan sering melihat kolom yang ditambahkan ke aliran baris oleh operator pembaruan tabel dasar. Dalam hal ini, Penghapusan Indeks Berkelompok menambahkan kolom kunci indeks tidak tercakup ke aliran. Data ini diperlukan oleh mesin penyimpanan untuk menemukan baris yang akan dihapus dari indeks yang tidak tercakup:

Detail daftar keluaran

Bagaimana perintah direplikasi? Apakah perintah SQL dikirim dan diproses pada setiap pelanggan? Atau SQL Server sedikit lebih pintar dari itu?

Pemotongan tidak diizinkan pada tabel yang diterbitkan menggunakan replikasi transaksional atau gabungan. Bagaimana penghapusan direplikasi tergantung pada jenis replikasi dan bagaimana hal itu dikonfigurasi. Misalnya, replikasi snapshot hanya mereplikasi tampilan point-in-time dari tabel menggunakan metode massal - perubahan inkremental tidak dilacak atau diterapkan. Replikasi transaksional bekerja dengan membaca catatan log dan menghasilkan transaksi yang sesuai untuk menerapkan perubahan pada pelanggan. Menggabungkan perubahan trek replikasi menggunakan pemicu dan tabel metadata.

Bacaan terkait: Mengoptimalkan kueri T-SQL yang mengubah data

Paul White mengatakan GoFundMonica
sumber