Use EXPLAIN

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:

  1. Latar belakang kenapa query optimization itu penting
  2. Apa itu EXPLAIN() dan kenapa kita membutuhkannya
  3. Cara menggunakan EXPLAIN()
  4. Cara membaca hasil EXPLAIN()
  5. 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 planner
  • EXPLAIN ANALYZE → eksekusi nyata + waktu aktual

⚠️ EXPLAIN ANALYZE benar-benar menjalankan query, hati-hati di production.


Cara Membaca Hasil EXPLAIN() #

Kolom penting yang wajib dipahami:

KolomArti
typeCara akses data (ALL, index, range, ref, const)
keyIndex yang digunakan
rowsEstimasi jumlah row yang dibaca
ExtraInformasi 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 #

typekeyrowsExtra
ALLNULL500000Using where

Analisis #

  • type = ALL → full table scan
  • key = NULL → tidak pakai index
  • 500 ribu row dibaca untuk 1 data

Solusi #

Tambahkan index:

CREATE INDEX idx_users_email ON users(email);

Setelah Optimasi #

typekeyrows
refidx_users_email1

✅ 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 #

typekeyrows
ALLNULL1,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 #

typekeyrows
rangeidx_orders_created_at15000

📉 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 scan
  • orders → nested loop besar

Solusi #

  1. Tambahkan index:
CREATE INDEX idx_users_country ON users(country);
  1. 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 #

  1. SELECT * di tabel besar
  2. ❌ Fungsi di kolom WHERE
  3. ❌ Index banyak tapi tidak sesuai query
  4. ❌ Optimasi tanpa melihat EXPLAIN
  5. ❌ 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.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact