Use Explain #
Dalam sistem yang sudah berjalan di production, masalah performa paling sering bukan ada di kode aplikasi, tapi di query database. Query yang terlihat “normal” bisa menjadi silent killer ketika data membesar.
Di sinilah EXPLAIN() berperan.
Artikel ini akan membahas:
- Latar belakang kenapa query optimization itu penting
- Apa itu
EXPLAIN()dan kenapa kita membutuhkannya - Cara menggunakan
EXPLAIN() - Cara membaca hasil
EXPLAIN() - Contoh nyata query lambat & bagaimana mengoptimalkannya
Latar Belakang #
Banyak engineer berpikir:
“Query ini cuma
SELECT, datanya juga nggak banyak…”
Masalahnya:
- Data selalu bertambah
- Akses query bersifat repetitif
- Beban concurrent user meningkat
- Query yang awalnya cepat, jadi bottleneck tanpa disadari
Penyebab umum query lambat:
- Tidak menggunakan index
- Salah desain index
- Full table scan
- Join berlebihan
- Filtering setelah data diambil
- Sorting di data besar tanpa index
Tanpa alat bantu, kita hanya menebak-nebak.
Apa Itu EXPLAIN()?
#
EXPLAIN() adalah perintah untuk meminta database menjelaskan bagaimana ia akan mengeksekusi sebuah query.
Bukan hasil data, tapi:
- Apakah pakai index atau tidak
- Urutan join
- Estimasi jumlah row yang dibaca
- Cost eksekusi
Contoh sederhana:
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';
Database akan menjawab:
“Saya akan mencari data seperti ini, lewat index ini, dengan estimasi sekian baris.”
Kenapa EXPLAIN() Penting?
#
Tanpa EXPLAIN():
- Kita mengoptimasi berdasarkan asumsi
- Perubahan index sering “trial and error”
- Sulit menjelaskan ke tim kenapa query ini lambat
Dengan EXPLAIN():
- Optimasi berbasis data
- Bisa memprediksi dampak query sebelum production
- Diskusi teknis jadi objektif
Cara Menggunakan EXPLAIN()
#
Dasar #
EXPLAIN SELECT * FROM orders WHERE user_id = 10;
Dengan eksekusi #
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 10;
EXPLAIN→ estimasi plannerEXPLAIN ANALYZE→ eksekusi nyata + waktu aktual
⚠️
EXPLAIN ANALYZEbenar-benar menjalankan query, hati-hati di production.
Cara Membaca Hasil EXPLAIN()
#
Kolom penting yang wajib dipahami:
| Kolom | Arti |
|---|---|
type | Cara akses data (ALL, index, range, ref, const) |
key | Index yang digunakan |
rows | Estimasi jumlah row yang dibaca |
Extra | Informasi tambahan (Using where, Using filesort, dll) |
Urutan type dari paling buruk → paling baik
#
ALL (Full Table Scan)
index
range
ref
eq_ref
const
system
Jika kamu melihat ALL di tabel besar → lampu merah 🚨
Query Lambat karena Full Table Scan #
Query #
SELECT * FROM users WHERE email = '[email protected]';
Hasil EXPLAIN
#
| type | key | rows | Extra |
|---|---|---|---|
| ALL | NULL | 500000 | Using where |
Analisis #
type = ALL→ full table scankey = NULL→ tidak pakai index- 500 ribu row dibaca untuk 1 data
Solusi #
Tambahkan index:
CREATE INDEX idx_users_email ON users(email);
Setelah Optimasi #
| type | key | rows |
|---|---|---|
| ref | idx_users_email | 1 |
✅ Query sekarang O(log n), bukan O(n)
Index Ada Tapi Tidak Dipakai #
Query #
SELECT * FROM orders
WHERE DATE(created_at) = '2026-01-01';
Hasil EXPLAIN
#
| type | key | rows |
|---|---|---|
| ALL | NULL | 1,200,000 |
Kenapa Index Tidak Dipakai? #
Karena:
DATE(created_at)
➡️ Fungsi pada kolom mematikan index
Solusi yang Benar #
SELECT * FROM orders
WHERE created_at >= '2026-01-01'
AND created_at < '2026-01-02';
Setelah Optimasi #
| type | key | rows |
|---|---|---|
| range | idx_orders_created_at | 15000 |
📉 Dari 1.2 juta → 15 ribu row
JOIN Lambat karena Salah Urutan & Index #
Query #
SELECT *
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.country = 'ID';
Masalah Umum #
- Tidak ada index di
users.country - Join dilakukan ke tabel besar tanpa filter awal
Hasil EXPLAIN (ringkas)
#
users→ full scanorders→ nested loop besar
Solusi #
- Tambahkan index:
CREATE INDEX idx_users_country ON users(country);
- Pastikan kolom join ter-index:
CREATE INDEX idx_orders_user_id ON orders(user_id);
Dampak #
- Filter user dilakukan lebih awal
- Join jauh lebih kecil
- Latency turun drastis
Anti-Pattern yang Sering Terjadi #
- ❌
SELECT *di tabel besar - ❌ Fungsi di kolom
WHERE - ❌ Index banyak tapi tidak sesuai query
- ❌ Optimasi tanpa melihat
EXPLAIN - ❌ Percaya ORM tanpa cek SQL-nya
Penutup #
EXPLAIN() bukan sekadar fitur database, tapi alat berpikir.
Dengan EXPLAIN():
- Kita memahami cara database bekerja
- Optimasi jadi ilmiah, bukan mitos
- Aplikasi lebih scalable & predictable
Rule of thumb: 👉 Kalau query penting, selalu lihat
EXPLAIN-nya.