Index bukan tombol “buat cepat”. Index adalah struktur data tambahan yang membantu MySQL menemukan baris dengan lebih sedikit pembacaan. Pilihan kolom dan urutannya harus mengikuti pola query nyata.
Mulai dari query lambat, bukan tebakan
EXPLAIN ANALYZE
SELECT id, customer_id, total, created_at
FROM orders
WHERE customer_id = 881
AND status = 'paid'
AND created_at >= '2026-01-01'
ORDER BY created_at DESC
LIMIT 50;Perhatikan jumlah rows yang diperiksa, access type, key yang dipilih, dan operasi sort. Query yang hanya mengembalikan 50 baris tetapi memindai jutaan baris adalah kandidat jelas.
Susun composite index mengikuti filter
CREATE INDEX idx_orders_customer_status_created
ON orders (customer_id, status, created_at DESC);Kolom equality biasanya ditempatkan lebih dulu, kemudian range atau ordering. Index di atas membantu filter customer dan status, lalu membaca tanggal dalam urutan yang dibutuhkan.
Index juga memiliki biaya
INSERT, UPDATE, dan DELETE harus memperbarui index.
Index besar dapat mengusir data penting dari buffer pool.
Statistik yang tidak akurat dapat menghasilkan plan buruk.
Dua index dengan prefix sama sering kali tidak diperlukan.
Perbaikan lain yang sering lebih besar dampaknya
- Jangan memakai
SELECT *untuk endpoint yang hanya butuh empat kolom. - Hindari fungsi pada kolom terindeks di bagian WHERE jika bisa memakai range.
- Batasi N+1 query dari ORM.
- Arsipkan data lama bila tabel operasional terlalu besar.
- Gunakan pagination yang tidak bergantung pada OFFSET besar.
-- Kurang efisien untuk halaman sangat jauh
SELECT * FROM orders ORDER BY id DESC LIMIT 50 OFFSET 500000;
-- Keyset pagination
SELECT id, total, created_at
FROM orders
WHERE id < :last_seen_id
ORDER BY id DESC
LIMIT 50;Ukur kembali setelah perubahan dengan data yang representatif. Optimasi selesai ketika latency, throughput, dan beban server membaik—bukan ketika query terlihat lebih canggih.
