Ich habe eine SQLite-Datenbank mit zwei Tabellen mit jeweils 50.000 Zeilen, die Namen von (falschen) Personen enthalten. Ich habe eine einfache Abfrage erstellt, um herauszufinden, wie viele Namen (Vorname, zweiter Vorname, Nachname) in beiden Tabellen vorkommen:
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;
Wenn außer den Primärschlüsseln keine Indizes vorhanden sind (für diese Abfrage irrelevant), wird dies schnell ausgeführt:
[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
Wenn ich jedoch den drei Spalten jeder Tabelle Indizes hinzufüge (insgesamt sechs Indizes):
CREATE INDEX `idx_uk_givenname` ON `fakenames_uk` (`givenname` )
//etc.
dann läuft es schmerzhaft langsam:
[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
Gibt es einen Reim oder Grund dafür?
Hier ist das Ergebnis EXPLAIN QUERY PLAN
für die Version ohne Indizes:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING AUTOMATIC COVERING INDEX (middleinitial=? AND surname=? AND givenname=?)
Dies ist mit Indizes:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING INDEX idx_us_middleinitial (middleinitial=?)
middleinitial
,surname
undgivenname
) enthält?