Eu tenho um banco de dados sqlite com duas tabelas, cada uma com 50.000 linhas, contendo nomes de pessoas (falsas). Eu construí uma consulta simples para descobrir quantos nomes existem (nome, inicial do meio, sobrenome) comuns a ambas as tabelas:
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;
Quando não há índices, exceto nas chaves primárias (irrelevantes para esta consulta), ela é executada rapidamente:
[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
Mas se eu adicionar índices às três colunas em cada tabela (seis índices no total):
CREATE INDEX `idx_uk_givenname` ON `fakenames_uk` (`givenname` )
//etc.
depois corre dolorosamente devagar:
[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
Existe alguma rima ou razão para isso?
Aqui está o resultado da EXPLAIN QUERY PLAN
versão sem índices:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING AUTOMATIC COVERING INDEX (middleinitial=? AND surname=? AND givenname=?)
Isto é com índices:
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING INDEX idx_us_middleinitial (middleinitial=?)
middleinitial
,surname
egivenname
)?