나는 (가짜) 사람들의 이름을 포함하는 두 개의 테이블이 각각 50,000 개의 행을 가진 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;
기본 키를 제외하고 (이 쿼리와 관련이없는) 인덱스가 없으면 빠르게 실행됩니다.
[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
그러나 각 테이블의 세 열에 인덱스를 추가하면 (6 개의 인덱스) 모두 :
CREATE INDEX `idx_uk_givenname` ON `fakenames_uk` (`givenname` )
//etc.
그런 다음 고통스럽게 느리게 실행됩니다.
[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
이것에 운율이나 이유가 있습니까?
EXPLAIN QUERY PLAN
인덱스가없는 버전 의 결과는 다음과 같습니다 .
0|0|0|SCAN TABLE fakenames_uk
0|1|1|SEARCH TABLE fakenames_usa USING AUTOMATIC COVERING INDEX (middleinitial=? AND surname=? AND givenname=?)
이것은 색인과 함께입니다 :
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
의 경우 인덱스 t(a,b,c)
는 포함하지만 포함 t(a,b)
하지 않습니다. 인덱스를 포함하는 이점은 전체 쿼리 결과를 인덱스에서 직접 가져올 수있는 반면, 포함되지 않은 인덱스는 관련 행을 빠르게 찾을 수 있지만 여전히 주 테이블 데이터를 참조하여 값을 선택해야한다는 것입니다.
middleinitial
,surname
및givenname
) 에 세 열을 모두 포함하는 포함 인덱스를 만들면 어떻게됩니까 ?