Lompat ke konten
Kembali ke modul

Data: Database dan SQL · 5/7

Index dan performa query

Kenapa query yang sama terasa instan di 100 baris tapi tidak terpakai di sejuta baris.

Baca 25 menit

Setelah pelajaran ini kamu bisa

  • Menjelaskan apa itu index dan apa biayanya
  • Membaca EXPLAIN QUERY PLAN dan mengenali full scan
  • Menentukan kolom mana yang layak diberi index
  • Menjelaskan kenapa sebuah index bisa diabaikan

Tanpa index, menemukan sebuah row berarti membaca setiap row sampai ada yang cocok. Itu full scan, dan itu tidak masalah untuk seratus row tapi tidak terpakai untuk sejuta row. Index adalah struktur terpisah yang terurut, yang memungkinkan database melompat langsung ke sana.

sql
CREATE INDEX bookings_venue_id ON bookings(venue_id);

-- Ask the database what it will actually do:
EXPLAIN QUERY PLAN SELECT * FROM bookings WHERE guest = ?;
Dijalankan terhadap SQLite proyek ini, rencana itu melaporkan `SCAN bookings` sebelum ada index, dan `SEARCH bookings USING INDEX bookings_guest (guest=?)` sesudahnya. SCAN berarti setiap row; SEARCH berarti ia melompat.

Besarnya perbedaannya layak dilihat sebagai pengukuran nyata. Pada tabel berisi 200.000 row di SQLite proyek ini, dua puluh pencarian lewat kolom teks tanpa index butuh 110,1 ms. Setelah menambahkan index pada kolom itu, dua puluh pencarian yang sama butuh 0,1 ms — sekitar 1700 kali lebih cepat, untuk satu baris SQL.

Coba sendiri

Kenapa selisihnya sebesar itu: scan bersifat linear, pencarian lewat index tidak. Jalankan dan perhatikan jumlah operasinya.

Hasil

Tekan Jalankan untuk melihat hasilnya.

Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.

Apa yang perlu diberi index

Beri indexKarena
Setiap foreign keyKamu akan terus-menerus melakukan join padanya
Kolom di WHERE yang sering dipakaiItulah gunanya index
Kolom yang sering kamu ORDER BYIndex yang terurut menghindari proses sorting
Kolom dengan constraint UNIQUEDatabase memberi index padanya otomatis

Proyek ini memberi index pada tepat dua hal di luar primary key-nya: sessions(user_id) dan lesson_progress(user_id). Keduanya foreign key yang difilter oleh setiap query dashboard. Tidak ada lagi yang diberi index, karena tidak ada lagi yang di-query seperti itu.

Kapan index diabaikan

sql
-- These prevent the index on `name` from being used:

WHERE LOWER(name) = 'ana'          -- a function on the column
WHERE name LIKE '%ana'             -- a leading wildcard: no sorted prefix
WHERE CAST(id AS TEXT) = '42'      -- a type change

-- These can use it:
WHERE name = 'Ana'
WHERE name LIKE 'Ana%'             -- trailing wildcard is fine
WHERE id = 42
Index diurutkan berdasarkan nilai kolomnya. Bungkus kolomnya dengan sebuah function dan urutan itu tidak berlaku lagi, jadi database tidak punya pilihan selain melakukan scan.

Tugas praktik

Terhadap database proyek ini, jalankan EXPLAIN QUERY PLAN SELECT * FROM lesson_progress WHERE user_id = 1 dan catat apakah hasilnya SCAN atau SEARCH. Lalu jalankan hal yang sama untuk WHERE lesson_id = 'react/state' dan bandingkan. Jelaskan perbedaannya memakai index yang dideklarasikan di features/db/index.ts.

Hasil yang diharapkan

SEARCH untuk user_id, SCAN untuk lesson_id — hanya yang pertama punya index.