Saya memiliki database sqlite dengan dua tabel, masing-masing dengan 50.000 baris, berisi nama-nama orang (palsu). Saya telah membuat kueri sederhana untuk mengetahui berapa banyak nama yang ada (nama yang diberikan, nama tengah, nama keluarga) yang umum untuk kedua tabel:
select count(*) from fakenames_uk inner join fakenames_usa on fakenames_uk.givenname=fakenames_usa.givenname and fakenames_uk.surname=fakenames_usa.surname and fakenames_uk.middleinitial=fakenames_usa.middleinitial;
Ketika tidak ada indeks kecuali pada kunci utama (tidak relevan dengan permintaan ini), itu berjalan dengan cepat:
[james@marlon Downloads] $ time sqlite3 generic_data_no_indexes.sqlite "select count(*) from fakenames_uk inner join fakenames_usa on fakenames_uk.givenname=fakenames_usa.givenname and fakenames_uk.surname=fakenames_usa.surname and fakenames_uk.middleinitial=fakenames_usa.middleinitial;"
131
real 0m0.115s
user 0m0.111s
sys 0m0.004s
Tetapi jika saya menambahkan indeks ke tiga kolom pada setiap tabel (enam indeks semuanya):
CREATE INDEX `idx_uk_givenname` ON `fakenames_uk` (`givenname` )
//etc.
lalu berjalan dengan sangat lambat:
[james@marlon Downloads] $ time sqlite3 generic_data.sqlite "select count(*) from fakenames_uk inner join fakenames_usa on fakenames_uk.givenname=fakenames_usa.givenname and fakenames_uk.surname=fakenames_usa.surname and fakenames_uk.middleinitial=fakenames_usa.middleinitial;"
131
real 1m43.102s
user 0m52.397s
sys 0m50.696s
Apakah ada sajak atau alasan untuk ini?
Inilah hasil EXPLAIN QUERY PLAN
untuk versi tanpa indeks:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING AUTOMATIC COVERING INDEX (middleinitial=? AND surname=? AND givenname=?)
Ini dengan indeks:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING INDEX idx_us_middleinitial (middleinitial=?)
SELECT c FROM t WHERE a=1 AND b=2
, indeks t(a,b,c)
mencakup tetapi t(a,b)
tidak. Manfaat dari indeks yang dicakup adalah bahwa seluruh hasil kueri dapat ditarik langsung dari indeks, sedangkan indeks yang tidak mencakup dengan cepat menemukan baris yang relevan tetapi masih perlu merujuk ke data tabel utama untuk memilih nilai-nilai.
middleinitial
,surname
dangivenname
)?