Saya punya contoh SQL Server 2008 dengan sekitar 150 kolom. Saya sebelumnya telah mengisi tabel ini dengan sekitar 12 juta entri, tetapi sejak itu membersihkan tabel dalam persiapan untuk kumpulan data baru.
Namun, perintah yang pernah berlari langsung pada sebuah meja kosong seperti count(*)
dan select top 1000
di SQL Management Studio
saat mengambil ribuan tahun untuk menjalankan.
SELECT COUNT(*) FROM TABLE_NAME
butuh lebih dari 11 menit untuk mengembalikan 0, dan SELECT TOP 1000
butuh hampir 10 menit untuk mengembalikan meja kosong.
Saya juga memperhatikan bahwa ruang kosong pada hard drive saya benar-benar menghilang (turun dari sekitar 100G ke 20G). Satu-satunya hal yang terjadi di antaranya adalah satu kueri yang saya jalankan:
DELETE FROM TABLE_NAME
Apa yang sedang terjadi?!?
TRUNCATE TABLE
bukanDELETE FROM
.Jawaban:
Anda telah diberi tahu tentang mengapa
TRUNCATE
akan jauh lebih cepat / lebih baik / lebih seksi daripadaDELETE
, tetapi masih ada pertanyaan yang harus diatasi:Mengapa
SELECT
lebih lambat setelahDELETE
selesai ?Itu karena
DELETE
hanya membayangi baris. Tabel ini hanya sebesar ketika memiliki 12M baris, meskipun tidak ada. Untuk menghitung baris (0), dibutuhkan waktu sebanyak yang diperlukan untuk menghitung 12M baris. Pada saatnya proses pembersihan hantu akan mengumpulkan sampah catatan hantu ini dan mengalokasikan halaman yang hanya berisi hantu, dan SELECT Anda akan mempercepat. Tetapi sekarang jika Anda check-Skipped Ghosted Records/sec
in perfmon mungkin meroket selamaSELECT COUNT(*)
. Anda juga bisa mempercepat hal-hal dengan membangun kembali tabel:ALTER TABLE ... REBUILD
.TRUNCATE
akan juga mengurus masalah ini, karena tidak meninggalkan hantu di belakang.Lihat juga Di dalam Mesin Penyimpanan: Pembersihan hantu secara mendalam .
sumber
DELETE
pernyataan menghapus baris dari tabel satu per satu, mencatat setiap baris dalamtransaction log
, serta memeliharalog sequence number (LSN)
informasi. Karena Anda menyebutkan meja Anda memiliki data yang sangat besar (12 juta catatan), setelah penghapusan Hard Disk Anda kehabisan ruang, periksa ukuran file Log Database Anda. Kemungkinan besar akan tumbuh.cara yang lebih baik adalah:
sumber
(Ini awalnya adalah komentar untuk jawaban @ DaveE, tapi saya sudah memasukkannya ke dalam jawabannya sendiri karena sudah lama)
TRUNCATE
adalah operasi yang dicatat. Itu harus dinyatakan tidak memenuhi syarat ACID. Namun, perbedaan antaraTRUNCATE
danDELETE
:TRUNCATE
hanya log halaman / luasan * yang dibebaskan, sedangkanDELETE
log setiap baris.TRUNCATE
umumnya akan menggunakan lebih sedikit kunci, karena dibutuhkan kunci meja dan kunci halaman, sebagai lawan dariDELETE
yang menggunakan kunci baris **.IDENTITY
urutan:TRUNCATE
mengatur ulang urutan identitas pada tabel, jika ada.(* Tingkat = 8 halaman.
TRUNCATE
Akan mencatat / menghapus luasan jika semuanya dari satu tabel itu, jika tidak maka akan mencatat / menghapus halaman dari luasan campuran.** Satu efek samping dari hal ini adalah bahwa
DELETE FROM TABLE
berpotensi dapat membiarkan halaman kosong dialokasikan ke tabel, tergantung pada apakah operasi bisa mendapatkan kunci tabel eksklusif atau tidak.)Jadi (kembali ke pertanyaan awal),
TRUNCATE TABLE
konklusif lebih baik daripadaDELETE FROM TABLE
jika Anda mengosongkan tabel tetapi ingin mempertahankan strukturnya (NB:TRUNCATE
tidak dapat digunakan pada tabel yang dirujuk oleh kunci asing dari tabel lain).Seperti tercantum dalam komentar @ Tullo, periksa juga model pemulihan basis data Anda - jika penuh, maka Anda harus mulai mengambil cadangan log, atau mengubah model pemulihan menjadi sederhana. Setelah Anda melakukan salah satu dari itu, Anda mungkin ingin mengecilkan file log Anda sebagai operasi sekali saja (NB: file log saja ) untuk mendapatkan kembali semua ruang kosong itu.
Akhirnya, hal lain yang perlu diperhatikan - tabel statistik. jalankan
UPDATE STATISTICS <TABLENAME>' after
TRUNCATE/
DELETE` sehingga optimizer kueri tidak tersandung oleh statistik lama.sumber
(CATATAN: Saya bukan DBA) DELETE adalah operasi yang dicatat, dan tidak membebaskan ruang yang digunakan. Anda mungkin memiliki log transaksi besar yang mengambil ruang dan pemindaian tabel berjalan di ruang tabel 'kosong'. Saya kira Anda perlu menghapus log transaksi dan mengecilkan basis data Anda. Artikel StackOverflow ini akan membantu Anda memulai.
Dan gunakan TRUNCATE TABLE ketika Anda ingin melakukan ini di masa depan.
EDIT: Pernyataan saya tentang TRUNCATE yang tidak dicatat salah. dihapus.
sumber