मेरे पास दो तालिकाओं के साथ एक sqlite डेटाबेस है, प्रत्येक में 50,000 पंक्तियों के साथ (नकली) लोगों के नाम हैं। मैंने यह पता लगाने के लिए एक सरल क्वेरी का निर्माण किया है कि कितने नाम हैं (दिए गए नाम, मध्य प्रारंभिक, उपनाम) जो दोनों तालिकाओं के लिए सामान्य हैं:
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
लेकिन अगर मैं प्रत्येक तालिका के तीन स्तंभों में अनुक्रमणिका जोड़ता हूं (सभी में छः अनुक्रमित):
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
)?