Seq Scan vs Index Scan vs Index-Only
Mengapa perencana memilih masing-masing opsi dan apa yang ditunjukkannya tentang kueri Anda.
Seq Scan vs Index Scan vs Index-Only adalah pelajaran Coding Interview Prep gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Coding Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Coding Interview Prep mencakup 4 pelajaran total.
Tiga Cara Membaca Tabel
Ketika perencana memerlukan baris dari sebuah tabel, perencana memilih salah satu dari tiga metode akses, dan pewawancara mengharapkan Anda menyebutkan semuanya:
- Pemindaian Berurutan, membaca setiap baris dalam tabel dari awal hingga akhir.
- Pemindaian Indeks, menelusuri indeks untuk menemukan baris yang cocok, lalu mengambil setiap baris dari tabel.
- Pemindaian Hanya-Indeks, menjawab sepenuhnya dari indeks tanpa menyentuh tabel sama sekali.
Mengetahui alasan perencana memilih masing-masing metode adalah inti pelajaran ini dan pertanyaan tingkat senior yang hampir pasti muncul.
Cara Kerja Pemindaian Berurutan
Pemindaian Berurutan membaca halaman-halaman tabel satu per satu dan menerapkan penyaring pada setiap baris. Tidak ada indeks yang digunakan.
Ini terdengar buruk, tetapi sering kali merupakan pilihan yang tepat. Pembacaan berurutan cepat bagi cakram (tanpa lompatan acak), jadi ketika kueri mengembalikan sebagian besar tabel, membaca semuanya lebih baik daripada melompat melalui indeks jutaan kali.
Contohnya: pindai orders, pertahankan baris yang memenuhi amount > 100. Jika sebagian besar pesanan melebihi 100, pemindaian berurutan adalah pilihan yang benar.
EXPLAIN SELECT * FROM orders WHERE amount > 100;
Seq Scan on orders (cost=0.00..18334.00 rows=900000 width=64)
Filter: (amount > 100)Cara Kerja Pemindaian Indeks
Pemindaian Indeks menggunakan B-tree untuk langsung menuju kunci yang cocok, lalu membaca baris terkait dari heap tabel.
Metode ini unggul ketika penyaringnya selektif, yaitu hanya mengembalikan sebagian kecil tabel. Mencari 5 baris melalui indeks lebih baik daripada membaca 10 juta baris.
Rencana menyebutkan indeks yang digunakannya. Setiap kecocokan memerlukan satu pencarian indeks ditambah satu pengambilan dari heap (pembacaan acak), sehingga pemindaian indeks kehilangan keunggulannya setelah mengembalikan terlalu banyak baris.
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
Index Scan using idx_orders_customer on orders
(cost=0.42..38.50 rows=12 width=64)
Index Cond: (customer_id = 42)Selektivitas Menentukan Pilihan
Konsep tunggal yang mendasari semua ini adalah selektivitas: bagian baris yang dipertahankan oleh sebuah predikat.
- Selektivitas tinggi (hanya sedikit baris yang cocok, seperti ID unik) mendukung Pemindaian Indeks.
- Selektivitas rendah (banyak baris yang cocok, seperti
status IS NOT NULL) mendukung Pemindaian Berurutan.
Aturan praktis yang umum: setelah kueri mengembalikan lebih dari sekitar 5 hingga 10 persen tabel, perencana sering memilih pemindaian berurutan karena pengambilan heap secara acak dari indeks menjadi lebih mahal daripada membaca semuanya secara berurutan.
Pemindaian Hanya-Indeks
Pemindaian Hanya-Indeks adalah yang tercepat di antara ketiganya. Jika setiap kolom yang diperlukan kueri sudah berada di dalam indeks, mesin tidak perlu menyentuh heap tabel sama sekali.
Kueri contoh hanya memilih customer_id dan melakukan penyaringan berdasarkan kolom tersebut, sedangkan indeksnya dibuat pada customer_id. Semua data yang diperlukan berada di dalam indeks, sehingga Postgres melaporkan Pemindaian Hanya-Indeks.
Metode ini menghindari pembacaan heap secara acak yang memperlambat pemindaian indeks biasa, sebuah keuntungan besar pada tabel yang memiliki banyak kolom.
EXPLAIN SELECT customer_id FROM orders WHERE customer_id = 42;
Index Only Scan using idx_orders_customer on orders
(cost=0.42..8.44 rows=12 width=4)
Index Cond: (customer_id = 42)Nuansa Peta Visibilitas
Pewawancara menyukai nuansa ini. Pemindaian hanya-indeks tetap harus memastikan bahwa setiap baris terlihat bagi transaksi Anda (MVCC), dan indeks saja tidak menyimpan informasi visibilitas.
Postgres menggunakan peta visibilitas: jika sebuah halaman ditandai sepenuhnya terlihat, heap dilewati; jika tidak, heap baris tersebut tetap harus diambil. Rencana menampilkan Heap Fetches: N.
Itulah sebabnya tabel yang baru diperbarui dapat menunjukkan banyak pengambilan heap dan memperlambat pemindaian hanya-indeks sampai VACUUM menyegarkan peta visibilitas.
Index Only Scan using idx_orders_customer on orders
(actual time=0.01..0.03 rows=12 loops=1)
Heap Fetches: 0Pemindaian Bitmap: Jalan Tengah
Ada metode keempat yang sering muncul: Pemindaian Heap Bitmap. Perencana memilihnya ketika sebuah predikat mencocokkan lebih banyak baris daripada yang ideal untuk pemindaian indeks biasa, tetapi lebih sedikit daripada seluruh tabel.
Pertama, metode ini membangun bitmap lokasi baris yang cocok dari indeks (Pemindaian Indeks Bitmap), kemudian mengambil halaman heap dalam urutan fisik, bukan urutan acak. Pengambilan secara berurutan jauh lebih murah daripada pembacaan terpencar pada pemindaian indeks biasa.
Bitmap Heap Scan on orders (cost=12.0..520.0 rows=8000)
Recheck Cond: (status = 'pending')
-> Bitmap Index Scan on idx_orders_status
(cost=0..12 rows=8000)
Index Cond: (status = 'pending')Mengapa Perencana Mengabaikan Indeks Anda
Pertanyaan wawancara klasik: Saya menambahkan indeks, tetapi rencana masih melakukan Pemindaian Berurutan. Mengapa? Alasan umumnya:
- Predikatnya tidak selektif, sehingga pemindaian memang lebih murah.
- Sebuah fungsi membungkus kolom:
WHERE lower(email) = ...tidak dapat menggunakan indeks biasa padaemail. - Ketidakcocokan tipe memaksa konversi implisit yang membuat indeks tidak dapat digunakan.
- Statistik usang, jalankan
ANALYZE. - Tabelnya sangat kecil, sehingga memindai beberapa halaman lebih baik daripada menanggung biaya tambahan indeks.
Diagnosis Praktis
Misalkan orders memiliki indeks pada created_at, tetapi kueri ini tetap melakukan pemindaian berurutan:
Penyebabnya adalah DATE(created_at). Membungkus kolom dalam fungsi berarti indeks pada created_at mentah tidak dapat digunakan. Perbaikannya adalah menulis ulang kueri sebagai predikat rentang yang membiarkan kolom apa adanya, atau membuat indeks ekspresi pada DATE(created_at).
-- Slow: function on the indexed column
WHERE DATE(created_at) = '2026-01-01'
-- Fast: bare column, range uses the index
WHERE created_at >= '2026-01-01'
AND created_at < '2026-01-02'Membandingkan Metode
Ingat perbandingan ini untuk wawancara:
- Pemindaian Berurutan, terbaik saat mengembalikan sebagian besar baris; I/O berurutan.
- Pemindaian Indeks, terbaik untuk pencarian selektif; penelusuran indeks ditambah pengambilan heap secara acak.
- Pemindaian Heap Bitmap, terbaik untuk jumlah kecocokan menengah; indeks menjadi bitmap, lalu pembacaan heap secara berurutan.
- Pemindaian Hanya-Indeks, tercepat ketika indeks mencakup setiap kolom yang diperlukan dan semua halaman terlihat.
Perencana memilih berdasarkan biaya yang diperkirakan, terutama berdasarkan selektivitas dan statistik.
Memaksa Pengujian (dan Mengapa Tidak di Produksi)
Untuk membuktikan suatu hal dalam pengembangan, Anda dapat mengarahkan perencana untuk sementara: SET enable_seqscan = off; memaksanya lebih memilih indeks sehingga Anda dapat membandingkan rencana.
Ini adalah trik diagnostik, bukan solusi produksi. Dalam wawancara, sebutkan bahwa solusi sebenarnya adalah statistik yang lebih baik, indeks yang sesuai, atau penulisan ulang predikat, bukan menonaktifkan fitur perencana secara global.
SET enable_seqscan = off;
EXPLAIN ANALYZE SELECT * FROM orders WHERE amount > 100;
SET enable_seqscan = on;Pemeriksaan Singkat
Sebuah kueri hanya memilih email dan melakukan penyaringan pada email, serta terdapat indeks B-tree pada email. Rencana menampilkan Index Only Scan. Mengapa ini lebih cepat daripada Pemindaian Indeks biasa?
Ringkasan
Hal-hal penting tentang metode akses:
- Pemindaian Berurutan unggul untuk kueri dengan selektivitas rendah; Pemindaian Indeks unggul untuk kueri yang selektif.
- Pemindaian Hanya-Indeks menghindari heap ketika indeks mencakup semua kolom yang diperlukan; perhatikan
Heap Fetchesdan peta visibilitas. - Pemindaian Heap Bitmap menjembatani kondisi tengah dengan mengambil halaman heap dalam urutan fisik.
- Perencana mengambil keputusan berdasarkan selektivitas dan statistik; fungsi pada kolom, ketidakcocokan tipe, dan statistik usang adalah alasan indeks diabaikan.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Seq Scan vs Index Scan vs Index-Only” gratis?
Ya — teks lengkap “Seq Scan vs Index Scan vs Index-Only” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Coding Interview Prep, upgrade ke CoddyKit PRO. Kursus Coding Interview Prep mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Seq Scan vs Index Scan vs Index-Only”?
Mengapa perencana memilih masing-masing opsi dan apa yang ditunjukkannya tentang kueri Anda. Kamu berlatih Coding Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Coding Interview Prep?
Tidak diperlukan pengalaman sebelumnya. Coding Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Seq Scan vs Index Scan vs Index-Only” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Coding Interview Prep ini?
Ya. Setiap pelajaran Coding Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Membaca Rencana EXPLAIN
- Seq Scan vs Index Scan vs Index-Only
- Algoritme Penggabungan: Nested Loop, Hash, Merge
- Menemukan dan Memperbaiki Kueri Lambat