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.
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 = ?;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.
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 index | Karena |
|---|---|
| Setiap foreign key | Kamu akan terus-menerus melakukan join padanya |
Kolom di WHERE yang sering dipakai | Itulah gunanya index |
Kolom yang sering kamu ORDER BY | Index yang terurut menghindari proses sorting |
Kolom dengan constraint UNIQUE | Database 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
-- 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 = 42Tugas 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.