Skip to content

Indeks SQL dijelaskan

Cheatsheet tentang jenis indeks SQL, pola desain, dan pemeliharaan.

Indeks menukar penyimpanan dan kecepatan tulis dengan kecepatan baca. Pilih strukturnya, batasi barisnya, dan kelola bloat-nya.

Tabel referensi · 31 entri
31 of 31 rows
Jenis indeks
Pohon seimbang untuk pemindaian kesetaraan, rentang, dan terurut. Bawaan untuk sebagian besar database.Gunakan untuk =, <, >, BETWEEN, ORDER BY. Lewati untuk pencarian full-text.
Indeks yang tingkat daunnya adalah tabel itu sendiri. Baris disimpan dalam urutan kunci. Satu per tabel.InnoDB mengelompokkan berdasarkan primary key. Tabel SQL Server tanpanya adalah heap.
Struktur terpisah yang menyimpan kunci plus penunjuk kembali ke tabel dasar. Banyak per tabel.Pada heap ia menyimpan row ID. Pada tabel clustered ia menyimpan clustering key.
Tabel hash hanya untuk pencarian kesetaraan. Kecocokan persis waktu konstan.Gunakan hanya untuk operasi =; rentang dan pengurutan butuh B-tree. Hash memory-optimized SQL Server butuh bucket count mendekati jumlah baris.
Generalized Inverted Index. Memetakan nilai ke baris. Dibuat untuk array dan full-text.Gunakan untuk jsonb, array, tsvector, pencarian trigram. Lebih lambat dibangun daripada B-tree.
Generalized Search Tree. Dapat diperluas untuk tipe non-skalar dan kueri tumpang-tindih.Gunakan untuk rentang geometri, kNN, batasan eksklusi. pg_trgm mempercepat LIKE.
GiST berpartisi ruang. Memecah data ke wilayah non-tumpang-tindih lewat pohon radix atau quad.Gunakan untuk titik, prefiks IP, dan pencocokan prefiks. Bukan untuk kueri tumpang-tindih; pakai GiST.
Block Range Index. Menyimpan min/maks per rentang blok. Jejak kecil.Gunakan pada tabel besar yang terurut secara fisik. Murah dibangun, selektivitas lemah.
Indeks yang disimpan sebagai segmen kolom alih-alih baris. Kompresi tinggi, eksekusi batch.Gunakan untuk pemindaian analitik atas banyak baris dan sedikit kolom. Pencarian satu baris lambat.
Indeks kata terbalik khusus di MySQL dan SQL Server. Dibangun per kolom teks.Gunakan MATCH AGAINST atau CONTAINS. Full-text Postgres memakai GIN pada tsvector sebagai gantinya.
Indeks Oracle yang menyimpan satu bitmap per nilai berbeda. Setiap bit menandai satu baris.Gunakan pada kolom kardinalitas rendah di warehouse yang padat baca. Tulis bersamaan terserialisasi per bitmap.
Kolom indeks yang dideklarasikan DESC. Kunci untuk kolom itu disimpan terbalik.Diperlukan untuk urut campuran seperti (a ASC, b DESC). Pengurutan DESC biasa juga bisa membaca indeks normal secara mundur.
Indeks MySQL 8 yang diabaikan optimizer. Tetap dipelihara pada setiap tulis.Sembunyikan indeks sebelum dijatuhkan untuk menguji dampaknya. Jadikan terlihat lagi tanpa rebuild.
Desain
Indeks multi-kolom. Kolom terdepan harus cocok dengan urutan filter kueri.Urutkan kesetaraan dulu, lalu rentang. Dua indeks tunggal tidak bisa menggantikan satu komposit.
Indeks pada predikat WHERE. SQL Server menyebutnya filtered index. Hanya mencakup baris yang cocok.Indeks hanya baris active='t'. Memangkas ukuran dan biaya tulis menjadi setengah.
B-tree dengan kolom non-kunci tambahan. Index-only scan menghindari lookup ke heap.Tambahkan kolom yang sering diambil lewat INCLUDE. Menjaga indeks tetap dapat diurutkan.
Indeks yang mewajibkan tidak ada nilai duplikat. Menolak insert yang bertabrakan.Gunakan untuk natural key dan batasan satu-ke-satu. UNIQUE NULL mengizinkan banyak NULL.
Indeks yang dibangun atas fungsi kolom, bukan kolomnya sendiri.Indeks lower(email) atau date_trunc('day', created_at). Kueri harus mengulang ekspresi yang persis.
Kelas operator. Menentukan bagaimana indeks membandingkan dan menyimpan tipe satu kolom.Set varchar_pattern_ops untuk LIKE 'abc%' tanpa case folding. Bawaan cocok untuk kesetaraan dan rentang.
Rencana yang menjawab kueri hanya dari halaman indeks. Heap tidak pernah dibaca.Butuh setiap kolom yang diambil berada di indeks atau INCLUDE list. Vacuum menjaga visibility map tetap mutakhir.
Kolom foreign key tidak mendapat indeks otomatis pada tabel yang mereferensikan.Indeks setiap kolom FK yang kamu join atau hapus lewatnya. Delete berjenjang memindai tabel anak tanpanya.
Pemeliharaan
Inspektur rencana. Menunjukkan sequential scan, pilihan indeks, estimasi biaya.Gunakan EXPLAIN (ANALYZE, BUFFERS). Seq Scan pada tabel 10M baris berarti indeks hilang.
Mengambil sampel kolom tabel untuk membangun statistik planner. Histogram mengarahkan pemilihan indeks.Jalankan setelah bulk load. Statistik basi menyebabkan seq scan pada kolom berindeks.
Setiap indeks menambah overhead tulis. Insert, update, delete membayar per indeks.Jatuhkan indeks yang tak terpakai. Lacak penggunaan di pg_stat_user_indexes.
View Postgres atas penggunaan per indeks. Menghitung scan dan tuple yang dibaca sejak reset statistik.Saring idx_scan = 0 untuk menemukan indeks tak terpakai. Reset penghitung dengan pg_stat_reset().
Membangun indeks tanpa memblokir baca atau tulis. Butuh dua pemindaian tabel.Tidak bisa berjalan dalam transaksi. Build yang gagal meninggalkan indeks INVALID untuk dijatuhkan.
Menghapus indeks dan membebaskan penyimpanannya. Mengambil lock eksklusif secara bawaan.Gunakan DROP INDEX CONCURRENTLY pada tabel sibuk. Periksa statistik penggunaan sebelum menghapus.
Membangun ulang indeks yang bloat. Mendapatkan kembali ruang dari dead tuple.Gunakan REINDEX CONCURRENTLY di produksi. Tanpanya lock memblokir tulis.
Dead tuple dan celah halaman yang menumpuk di tabel MVCC dan indeksnya.Ukur dengan pgstattuple. Vacuum sering; REINDEX saat ruang mati mendominasi.
Persentase halaman yang dipadatkan saat tulis. Ruang bebas menyerap update mendatang.Turunkan ke 70-90 pada tabel hot-update. Halaman penuh memaksa page split.
Menulis ulang tabel terurut secara fisik menurut indeks. Operasi sekali jalan.Berpasangan dengan BRIN untuk blok terurut. Urutan tidak dipertahankan pada tulisan berikutnya.