Perbedaan MyISAM dan InnoDB MySQL

saya pernah mewarisi project lama yang tabelnya memakai MyISAM, dan langsung merasakan bedanya begitu ingin memakai foreign key dan transaksi: tidak bisa. sejak itu, InnoDB selalu menjadi pilihan bawaan saya untuk aplikasi baru. artikel ini menjelaskan perbedaan keduanya secara praktis, termasuk kapan MyISAM masih layak dipakai.
1. apa itu storage engine?
storage engine adalah komponen MySQL yang menentukan bagaimana data disimpan dan diambil dari disk. setiap tabel bisa pakai engine berbeda. MySQL mendukung beberapa engine: InnoDB (default), MyISAM, MEMORY, CSV, Archive, dan lain-lain.
sejak MySQL 5.5 (2010), InnoDB jadi default karena support fitur modern: transaksi ACID, foreign key, row-level locking, dan crash recovery. MyISAM masih ada untuk backward compatibility, tapi jarang dipakai di project baru.
2. perbandingan lengkap
| Aspek | MyISAM | InnoDB |
|---|---|---|
| Transaction (ACID) | ❌ tidak | ✅ ya |
| Foreign Key | ❌ tidak | ✅ ya |
| Locking | table-level | row-level |
| Full-text search | ✅ ya (native) | ✅ (MySQL 5.6+) |
| Crash recovery | ❌ rentan korup | ✅ auto recovery |
| Auto-increment | lebih cepet | sedikit lebih lambat |
| Compressed tables | ✅ ya | ✅ (MySQL 5.7+) |
| Cocok untuk | read-heavy, data warehouse | write-heavy, aplikasi transaksional |
| Memory usage | lebih rendah | lebih tinggi (buffer pool) |
| MVCC | ❌ tidak | ✅ ya |
| TABLESIZE on disk | lebih kecil | lebih besar (overhead) |
| Default sejak | MySQL 3.23 (1999) | MySQL 5.5 (2010) |
penjelasan beberapa istilah:
- ACID: Atomicity, Consistency, Isolation, Durability.empat sifat transaksi database yang reliable.
- MVCC: Multi-Version Concurrency Control. InnoDB bisa baca data lama saat transaksi lain sedang update, tanpa lock.
- Buffer pool: InnoDB cache data di RAM untuk performa. ukuran default 128MB, bisa diset sampai 80% RAM.
3. transaksi: kenapa penting?
transaksi menjamin sekelompok query jalan sebagai satu unit: semua sukses, atau semua di-rollback. ini penting untuk aplikasi yang handle uang, stok, atau data kritis.
contoh tanpa transaksi:
-- Tanpa transaksi, jika query ke-2 gagal, uang sudah terpotong tapi stok belum berkurang
UPDATE akun SET saldo = saldo - 100000 WHERE id = 1;
UPDATE produk SET stok = stok - 1 WHERE id = 5; -- misal gagal, data tidak konsisten
dengan transaksi:
START TRANSACTION;
UPDATE akun SET saldo = saldo - 100000 WHERE id = 1;
UPDATE produk SET stok = stok - 1 WHERE id = 5;
-- Kalau semua OK
COMMIT;
-- Kalau ada error, panggil ROLLBACK untuk undo semua
MyISAM tidak support transaksi. kalau aplikasi crash di antara dua query, data bisa korup. InnoDB support transaksi ACID penuh, jadi aman.
4. row-level vs table-level locking
locking adalah mekanisme agar dua query tidak konflik modify data yang sama.
table-level locking (MyISAM): kalau satu query lagi update tabel, semua row di tabel itu di-lock. query lain (bahkan yang read) harus menunggu.
-- Query ini lock SELURUH tabel users
UPDATE users SET status = 'active' WHERE id = 5;
-- Query ini harus menunggu, meskipun cuma mau baca user id 100
SELECT * FROM users WHERE id = 100;
row-level locking (InnoDB): hanya row yang di-update yang di-lock. row lain tetap bisa diakses paralel.
-- Lock hanya row id=5
UPDATE users SET status = 'active' WHERE id = 5;
-- Query ini bisa langsung jalan paralel
SELECT * FROM users WHERE id = 100;
untuk aplikasi dengan banyak concurrent user, InnoDB jauh lebih cepet karena tidak blocking.
5. cara cek engine tabel
ada beberapa cara cek engine sebuah tabel:
-- Cara 1: SHOW TABLE STATUS
SHOW TABLE STATUS WHERE Name = 'users';
output:
Name: users
Engine: InnoDB
Version: 10
Row_format: Dynamic
...
-- Cara 2: SHOW CREATE TABLE
SHOW CREATE TABLE users;
output:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nama` varchar(100),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Cara 3: query INFORMATION_SCHEMA untuk cek banyak tabel sekaligus
SELECT
TABLE_NAME,
ENGINE,
TABLE_ROWS
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'nama_database'
ORDER BY ENGINE, TABLE_NAME;
-- Cara 4: cek default engine server
SHOW VARIABLES LIKE 'default_storage_engine';
6. cara ubah engine tabel
kalau tabel masih MyISAM dan mau migrate ke InnoDB:
-- Ubah satu tabel
ALTER TABLE users ENGINE = InnoDB;
perhatian:
- proses ini copy data dari tabel lama ke tabel baru. untuk tabel besar (juta baris), bisa makan waktu lama dan lock tabel sementara.
- backup dulu sebelum alter. kalau gagal, data aman di backup.
- setelah alter, cek foreign key dan index sudah benar.
untuk convert banyak tabel sekaligus:
-- Generate ALTER TABLE untuk semua tabel MyISAM
SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' ENGINE=InnoDB;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'nama_database'
AND ENGINE = 'MyISAM';
jalankan output dari query itu.
alternatif tools:
mysqldumplalu restore dengan engine default InnoDB.pt-online-schema-change(Percona Toolkit) untuk alter tabel besar tanpa lock lama.
7. cara setting default engine
secara global, default engine diset di konfigurasi MySQL (my.cnf atau my.ini):
[mysqld]
default-storage-engine = InnoDB
per session, bisa set default engine saat login:
SET default_storage_engine = InnoDB;
per tabel saat CREATE:
CREATE TABLE produk (
id INT PRIMARY KEY AUTO_INCREMENT,
nama VARCHAR(100)
) ENGINE = InnoDB;
kalau tabel sudah ada tapi tidak ada ENGINE=, dia pakai default session atau global.
8. kapan pakai MyISAM?
meskipun InnoDB lebih direkomendasikan, MyISAM masih punya use case:
MyISAM cocok untuk:
- read-heavy data warehouse yang tidak butuh update. misal log analytics, historical reports.
- lookup table kecil yang read-only. misal tabel provinsi, kabupaten.
- full-text search di MySQL < 5.6. sebelum InnoDB support full-text, MyISAM satu-satunya. sekarang sudah tidak relevan.
- temporary table yang performanya kritis dan tidak butuh durability.
MyISAM tidak cocok untuk:
- aplikasi web modern (butuh transaksi + foreign key).
- data yang sering di-update (risiko korup saat crash).
- aplikasi yang butuh data konsistensi tinggi.
9. kapan pakai InnoDB?
InnoDB cocok untuk hampir semua kasus modern:
- aplikasi web (CMS, e-commerce, social media).
- aplikasi finansial (butuh transaksi).
- sistem yang butuh foreign key.
- data yang sering di-update.
- aplikasi yang butuh crash recovery.
- data dengan concurrent access banyak.
aturan praktis: pakai InnoDB kecuali ada alasan kuat untuk MyISAM.
10. tips optimasi InnoDB
kalau pakai InnoDB, beberapa setting yang bisa tune untuk performa (update 2026, MySQL 8.0+):
[mysqld]
# Ukuran buffer pool (cache data + index di RAM)
# Default 128MB, naikkan sampai 50-80% RAM untuk server dedicated
innodb_buffer_pool_size = 4G
# Ukuran log file
innodb_log_file_size = 512M
# Buffer pool instances (untuk RAM besar, multiple instances untuk reduce contention)
innodb_buffer_pool_instances = 4
# File per table (default ON sejak 5.7, biar tiap tabel punya file .ibd sendiri)
innodb_file_per_table = 1
# Row format modern DYNAMIC sudah default sejak 5.7, tidak perlu set Barracuda/Large Prefix manual
# Parameter innodb_file_format dan innodb_large_prefix sudah deprecated sejak 5.7 dan dihapus di 8.0
setelah ubah setting, restart MySQL. monitor dengan SHOW ENGINE INNODB STATUS atau query INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS untuk lihat efektivitas cache.
11. cek engine yang dipakai di database
cara lihat ringkasan engine semua tabel di satu database:
SELECT
ENGINE,
COUNT(*) AS jumlah_tabel,
SUM(DATA_LENGTH + INDEX_LENGTH) AS total_size_bytes,
ROUND(SUM(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS total_size_mb
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE()
GROUP BY ENGINE
ORDER BY jumlah_tabel DESC;
berguna saat migrasi dari MyISAM ke InnoDB untuk estimasi waktu dan dampak storage.
12. foreign key: cuma InnoDB
foreign key sangat penting untuk menjaga data konsisten, tapi MyISAM tidak mendukungnya.
contoh foreign key di InnoDB:
-- Tabel orders dengan foreign key ke users
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
total DECIMAL(10, 2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE = InnoDB;
dengan foreign key:
- tidak bisa insert
orderdenganuser_idyang tidak ada di tabelusers. - kalau
userdihapus, semuaorder-nya ikut terhapus (ON DELETE CASCADE).
MyISAM mengabaikan foreign key ini. kalau CREATE TABLE di MyISAM dengan FOREIGN KEY, dia tetap dibuat tapi constraint tidak diterapkan. ini sering bikin bug data yang susah di-debug.
detail lebih lanjut soal foreign key, baca tutorial primary key dan foreign key (10/29 publish).
Kesimpulan
- InnoDB = engine modern, support transaksi ACID, foreign key, row-level locking, crash recovery
- MyISAM = engine lama, lebih cepet untuk read-heavy sederhana, tapi tidak support fitur modern
- sejak MySQL 5.5, InnoDB jadi default dan direkomendasikan untuk hampir semua kasus
- cara cek engine:
SHOW TABLE STATUS,SHOW CREATE TABLE, atau query INFORMATION_SCHEMA - cara ubah engine:
ALTER TABLE nama_tabel ENGINE = InnoDB; - untuk aplikasi baru, selalu pakai InnoDB kecuali ada use case spesifik yang butuh MyISAM
- foreign key hanya jalan di InnoDB, MyISAM mengabaikannya
Pertanyaan yang Sering Diajukan
Apa beda utama MyISAM dan InnoDB?
MyISAM engine lama, tidak support transaksi dan foreign key. InnoDB engine modern dengan dukungan ACID transaction, foreign key, row-level locking, dan crash recovery. InnoDB jadi default sejak MySQL 5.5.
Mana yang lebih cepet, MyISAM atau InnoDB?
tergantung workload. untuk read-heavy sederhana, MyISAM sedikit lebih cepet. untuk workload campuran (read+write) dan yang butuh transaksi, InnoDB jauh lebih cepet dan aman.
Apakah InnoDB selalu lebih baik dari MyISAM?
untuk hampir semua kasus modern, ya. InnoDB mendukung fitur yang MyISAM tidak punya: transaksi, foreign key, row-level locking. MyISAM hanya untuk kasus spesifik seperti data warehouse yang read-only.
Bagaimana cara cek engine sebuah tabel?
SHOW TABLE STATUS WHERE Name = "nama_tabel"; atau SHOW CREATE TABLE nama_tabel; di bagian ENGINE= akan keliatan. ada juga query INFORMATION_SCHEMA.TABLES untuk cek banyak tabel sekaligus.
Bisa ubah engine tabel yang sudah ada?
bisa, pakai ALTER TABLE nama_tabel ENGINE = InnoDB; proses ini copy data, jadi di tabel besar bisa makan waktu dan lock sementara. backup dulu sebelum alter.
Kenapa InnoDB sekarang jadi default?
sejak MySQL 5.5 (2010), InnoDB jadi default engine karena kebanyakan kasus modern butuh transaksi dan foreign key. MyISAM masih ada di MySQL untuk backward compatibility, tapi tidak direkomendasikan untuk project baru.
Apa itu row-level locking vs table-level locking?
table-level locking: ketika satu query update tabel, semua row lain di tabel itu di-lock. row-level: hanya row yang di-update yang di-lock, row lain masih bisa diakses. InnoDB row-level, MyISAM table-level.
Apakah foreign key penting di MySQL?
sangat penting untuk menjaga integritas data. foreign key memastikan nilai di kolom harus ada di tabel referensi, atau NULL. tanpa foreign key, aplikasi harus handle validasi secara manual, rentan bug.

