Soal 1Mengapa Index-Only Scan menghindari kembali ke tabel dasar?
Index-Only Scan — Indeks yang Melewati Tabel
Artikel ini adalah bagian dari Kursus SQL, yang membantu Anda menguasai keterampilan SQL praktis dari nol, mulai dari dasar hingga kueri kompleks dan penyetelan SQL.
Taruh setiap kolom yang disentuh kueri ke dalam indeks dan perjalanan kembali ke tabel dasar hilang. Inilah Index-Only Scan (juga dikenal sebagai covering index). Kamu akan mempelajari kondisi yang membuatnya bekerja, bagaimana ia rusak begitu satu kolom hilang, dan cara melipat kolom filter WHERE ke dalam satu indeks, semua diverifikasi dengan EXPLAIN QUERY PLAN.
Lewati lookup tabel — Index-Only Scan
Lookup indeks biasa menemukan baris target di indeks, lalu kembali ke tabel dasar untuk membaca kolom lain satu baris pada satu waktu.
Perjalanan kembali ini disebut table lookup (langkah menarik baris dari tabel dasar lewat indeks).
Ketika result set besar, perjalanan pulang-pergi itu menumpuk dan mulai memakan waktu nyata.
Kalau kamu memakai indeks yang berisi setiap kolom yang dirujuk kueri, semua nilai ada di sana di indeks, dan tidak perlu kembali ke tabel itu sendiri.
Pola ini, di mana indeks saja mengantarkan hasil, disebut Index-Only Scan (indeks yang mencakup setiap kolom yang disentuh kueri juga dikenal sebagai covering index).
-- Mengagregasi region dengan indeks yang hanya berisi region
-- Kolom yang dirujuk (region) sepenuhnya di dalam indeks → tidak ada perjalanan kembali ke tabel dasar
DROP INDEX IF EXISTS ix_demo;
CREATE INDEX ix_demo ON perf_sales(region);
EXPLAIN QUERY PLAN
SELECT region, COUNT(*)
FROM perf_sales
GROUP BY region;
Lewatkan satu kolom saja dan kamu kembali ke tabel dasar
Index-Only Scan hanya terjadi ketika setiap kolom yang disentuh kueri — di SELECT, WHERE, GROUP BY, dan sebagainya — ada di dalam indeks.
Lewatkan satu kolom saja dan database harus kembali ke tabel dasar untuk membacanya, dan USING COVERING INDEX hilang dari plan.
Misalnya, dengan indeks pada (emp_id, amount), menulis SELECT emp_id, SUM(amount), region menambah region, yang tidak ada di indeks — jadi kueri menuju kembali ke tabel dasar untuk mengambilnya.
-- Dengan indeks pada (region, amount),
-- menambah product ke kolom yang dirujuk merusak Index-Only Scan
DROP INDEX IF EXISTS ix_demo;
CREATE INDEX ix_demo ON perf_sales(region, amount);
-- region, SUM(amount) saja → sepenuhnya tercakup oleh indeks
EXPLAIN QUERY PLAN
SELECT region, SUM(amount) FROM perf_sales GROUP BY region;
-- Tambah product → tidak ada di indeks, jadi kembali ke tabel dasar
EXPLAIN QUERY PLAN
SELECT region, SUM(amount), MAX(product) FROM perf_sales GROUP BY region;
Pertahankan Index-Only Scan dengan menyertakan kolom filter WHERE juga
SELECT bukan satu-satunya tempat kolom muncul di kueri kamu.
Kolom filter WHERE juga dihitung sebagai kolom yang disentuh kueri, jadi mereka perlu ada di indeks juga — kalau tidak kamu masih akan kembali ke tabel dasar.
Lipat semuanya ke dalam satu indeks dalam urutan "kolom filter → kolom output / agregat", dan baik penyaringan maupun pengambilan nilai selesai di dalam indeks yang sama.
Misalnya, untuk memfilter dengan WHERE region = 'East' dan menghitung SUM(amount), taruh kolom filter region pertama dan kolom agregat amount kedua: (region, amount).
Indeks mempersempit ke baris target berdasarkan region dan membaca amount dari indeks yang sama, jadi tidak ada perjalanan kembali ke tabel dasar yang diperlukan.
-- Lipat kolom filter (status) dan kolom agregat (amount) ke dalam satu indeks
DROP INDEX IF EXISTS ix_demo;
CREATE INDEX ix_demo ON perf_sales(status, amount);
EXPLAIN QUERY PLAN
SELECT SUM(amount)
FROM perf_sales
WHERE status = 'pending';
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Diberikan indeks pada (emp_id, amount), kueri mana yang merusak Index-Only Scan dan kembali ke tabel dasar?
Soal 3Untuk kueri yang memfilter dengan WHERE region = 'East' dan menghitung SUM(amount), indeks mana yang mendukung Index-Only Scan?