Soal 1Mana deskripsi DELETE dan TRUNCATE yang benar?
TRUNCATE — Penghapusan Massal yang Cepat dan High Water Mark
Panduan visual untuk perbedaan antara DELETE dan TRUNCATE: cara kerja High Water Mark (HWM), apakah kamu bisa rollback setelah menjalankannya, alasan sesungguhnya di balik perbedaan kecepatan, dan cara memilih di antara mereka di Oracle / PostgreSQL / MySQL.
Kode di artikel ini ditujukan untuk RDBMS produksi
Sintaks TRUNCATE TABLE di artikel ini adalah bentuk yang dipakai oleh RDBMS produksi seperti MySQL / PostgreSQL / Oracle / SQL Server. Konsol browser untuk kursus ini (yang memakai SQLite) tidak menerima kata kunci TRUNCATE secara langsung. Di SQLite, DELETE FROM tabel; punya efek yang sama, dan truncate optimization internal membuatnya berjalan secepat TRUNCATE.
TRUNCATE — menghapus setiap baris, dengan cepat
Ada dua cara untuk menghapus setiap baris di tabel sekaligus. Yang satu adalah DELETE FROM tabel; (tanpa WHERE), yang sudah dibahas di artikel sebelumnya. Yang lain adalah `TRUNCATE TABLE tabel;`, topik artikel ini. Keduanya meninggalkan tabel kosong, tapi bagaimana caranya dan seberapa cepat berjalan benar-benar berbeda.
DELETE adalah perintah DML (Data Manipulation Language) yang menghapus baris satu per satu, meninggalkan entri log untuk setiap penghapusan. TRUNCATE, di sisi lain, condong ke DDL (Data Definition Language) — ia mereset seluruh tabel tanpa pencatatan per baris, hampir seperti definisi tabelnya sendiri dibuat ulang dari awal.
-- 1) DELETE semuanya (log delete per baris, bisa di-rollback)
DELETE FROM customer;
-- 2) TRUNCATE semuanya (reset sekali jalan, tanpa log per baris, biasanya commit langsung)
TRUNCATE TABLE customer;
-- Catatan: konsol kursus ini (SQLite) tidak menerima TRUNCATE.
-- DELETE FROM customer; mendapat truncate optimization yang sama secara internal dan berjalan cepat.
Perbedaan antara MySQL / PostgreSQL / Oracle
Sintaks TRUNCATE TABLE tabel; itu sendiri sama di MySQL / PostgreSQL / Oracle / SQL Server, tapi perilaku detailnya berbeda per DB.
- MySQL: Diperlakukan sebagai DDL, tidak bisa di-rollback, AUTO_INCREMENT di-reset
- PostgreSQL: Bisa di-rollback, RESTART IDENTITY mereset sequence juga
- Oracle: Diperlakukan sebagai DDL, tidak bisa di-rollback, REUSE STORAGE / DROP STORAGE membuatmu bisa mengontrol cara storage dikembalikan
- SQL Server: Bisa di-rollback
High Water Mark — apa yang ada di balik perbedaan kecepatan
Kunci untuk memahami perbedaan kecepatan antara DELETE dan TRUNCATE adalah konsep High Water Mark (HWM). HWM adalah penanda yang menunjuk ke blok storage tertinggi yang pernah dipakai tabel. Istilah ini berasal dari Oracle, tapi PostgreSQL / SQL Server / MySQL (InnoDB) semuanya punya optimisasi setara yang bekerja secara internal.
Saat DB melakukan full scan (sapu baris per baris seperti SELECT * FROM tabel), ia membaca setiap blok dari awal tabel sampai HWM secara berurutan. Semakin tinggi HWM, semakin banyak blok yang harus dibaca — dan karena ia tidak melewati blok kosong, scan bisa lambat bahkan di tabel kosong kalau HWM-nya tinggi.
Perilaku krusial di sini adalah DELETE tidak menurunkan HWM. Saat kamu menjalankan DELETE FROM tabel; untuk menghapus setiap baris, isi tabel jadi kosong, tapi blok-bloknya sendiri tetap di segment. HWM tetap di block 5. Jalankan SELECT COUNT(*) FROM tabel; berikutnya, dan walau jumlah baris adalah 0, DB membaca setiap blok pada atau di bawah HWM sampai akhir — memakan waktu yang kira-kira sama seperti sebelum delete.
TRUNCATE TABLE tabel; adalah perintah yang mereset HWM kembali ke awal tabel, secara instan menyusutkan target full-scan menjadi 0 blok. Itulah alasan sesungguhnya kenapa TRUNCATE digambarkan sebagai "instan bahkan di tabel besar."
DELETE tidak menyusutkan datanya?
Saya pernah mengalami situasi di produksi di mana saya menjalankan DELETE untuk mengurangi ukuran data, tapi pemakaian storage hampir tidak turun.
Penyebabnya persis ini: HWM tidak turun. DELETE hanya menghapus baris secara logis, sementara blok (page) yang sudah direservasi tabel tetap di tempat. File di disk masih menyimpan area itu, jadi dari perspektif OS ukuran datanya tidak berubah.
Saat kamu benar-benar ingin menyusutkan storage, jalankan perintah reorganisasi per-DB (VACUUM FULL di PostgreSQL, OPTIMIZE TABLE di MySQL InnoDB, ALTER TABLE ... SHRINK SPACE di Oracle), atau pakai TRUNCATE untuk full wipe.
Memilih antara DELETE dan TRUNCATE
Dalam praktik, pilihannya bukan sekadar "TRUNCATE untuk semuanya, DELETE saat butuh kondisi." Faktor sebenarnya adalah apakah kamu butuh rollback, apakah trigger harus ter-fire, dan seberapa penting kecepatan pemrosesan. Tabel perbandingan di bawah adalah checklist standar.
| Item | DELETE | TRUNCATE |
|---|---|---|
| Granularitas | Per baris | Seluruh tabel |
| Klausa WHERE | Diperbolehkan | Tidak diperbolehkan (selalu semua baris) |
| Kecepatan (tabel besar) | Lambat (proses per baris) | Cepat (instan) |
| Rollback setelah eksekusi | Mungkin | Tergantung DB (Oracle / MySQL: tidak) |
| Trigger ter-fire | Ter-fire | Umumnya tidak ter-fire |
| AUTO_INCREMENT | Dipertahankan | Reset (tergantung DB) |
| High Water Mark | Tidak bergerak | Reset |
| Log delete | Entri per baris (besar) | Minimal |
| Klasifikasi | DML | DDL (tergantung DB) |
Jebakan TRUNCATE
TRUNCATE itu cepat dan praktis, tapi cenderung jadi operasi yang tidak bisa kamu tarik kembali. Hati-hati dengan:
- Beberapa DB commit saat eksekusi (Oracle / MySQL). Di produksi, jalankan SELECT COUNT(*) lebih dulu untuk memastikan jumlah baris sebelum menjalankannya
- `AUTO_INCREMENT` di-reset (tergantung DB). Kalau ID-nya terekspos ke sistem eksternal atau URL, hati-hati dengan tabrakan setelah reset
- Constraint foreign key bisa menghalanginya (kebanyakan DB). Kalau subscription mereferensikan customer, kamu perlu mengosongkan tabel anaknya dulu untuk TRUNCATE customer
- Trigger umumnya tidak ter-fire. Trigger adalah mekanisme DB yang otomatis menjalankan SQL sebagai respons terhadap insert / update / delete baris — misalnya, "tulis entri audit log ke tabel lain setiap kali baris dihapus." DELETE memicu trigger ini baris demi baris, tapi TRUNCATE tidak beroperasi di level baris, jadi audit log dan catatan serupa tidak akan dibuat
Gunakan TRUNCATE saat kamu butuh kecepatan maksimal untuk wipe massal data besar; selain itu DELETE WHERE atau DELETE yang bisa di-rollback adalah pilihan yang lebih aman.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Mana deskripsi terbaik dari High Water Mark (HWM)?
Soal 3Tepat setelah mengosongkan tabel berisi 1 juta baris dengan DELETE FROM tabel; (tanpa WHERE), kamu menjalankan SELECT COUNT(*) FROM tabel;. Mana perilaku yang benar?