2014-09-02 40 views
1

我無法決定索引。 像我有以下查詢其花費過多時間用於執行:SQLite索引

select count(rn.NODE_ID) as Count, 
     rnl.[ISO_COUNTRY_CODE] as Country, 
     rnl.[FUNCTIONAL_CLASS] as Functional_Class 
from RDF_NODE as rn, 
    RDF_LINK as rl, 
    RDF_NAV_LINK as rnl 
where rl.[LINK_ID] = rnl.[LINK_ID] 
    AND rn.NODE_ID IN (rl.[NONREF_NODE_ID], rl.[REF_NODE_ID]) 
GROUP BY rnl.[ISO_COUNTRY_CODE], 
     rnl.[FUNCTIONAL_CLASS] 

雖然我使用EXPLAIN查詢計劃:具有索引

 
0 0 0 SCAN TABLE RDF_NODE AS rn USING COVERING INDEX NODE (~1000000 rows) 
0 1 2 SCAN TABLE RDF_NAV_LINK AS rnl (~6645278 rows) 
0 2 1 SEARCH TABLE RDF_LINK AS rl USING INDEX sqlite_autoindex_RDF_LINK_1 (LINK_ID=?) (~1 rows) 
0 0 0 EXECUTE LIST SUBQUERY 1 
0 0 0 USE TEMP B-TREE FOR GROUP BY 

所有表。

SCAN和SEARCH有什麼區別? 我們能否更改訂單?

+0

什麼是索引? – 2014-09-02 08:48:49

+0

'SCAN'是所有行必須迭代的操作 'SEARCH'似乎是SQL Server中所謂的'SEEK',其中正確的索引使用是可能的,並且並非所有行都必須迭代以找到正確的 – DrCopyPaste 2014-09-02 08:50:50

+0

這是有道理的,因爲這'從RDF_NODE作爲rn,RDF_LINK作爲rl,RDF_NAV_LINK作爲rnl'是一個交叉連接,並且它總是有意義遍歷這些表中的所有行來交叉連接它們,但可能是一個'INNER JOIN '會更有效地滿足你的需求。 – DrCopyPaste 2014-09-02 08:54:02

回答

1

SCAN遍歷表中的所有行(按它們存儲在表中的順序,通常根本沒有順序),而SEARCH則從表中查找單個行。

SQLite實現所有連接作爲嵌套循環連接。 最外層的表總是通過一個SCAN來訪問(除非有一個WHERE子句限制要返回的行)。 所有其餘的表格都應該通過SEARCH進行訪問以查找匹配的記錄;另一個SCAN表示沒有可用於加速查找的索引,因此查找每個匹配項需要搜索整個表。


對於這個特定的查詢,大的減速是用於實現GROUP BY的臨時表。 如果所有的分組列在一個單一的指標,這是沒有必要的:

CREATE INDEX UseABetterIndexNameHere 
    ON RDF_NAV_LINK(ISO_COUNTRY_CODE, FUNCTIONAL_CLASS); 

RDF_NAV_LINKRDF_LINK之間的連接需要RDF_LINK行是按照其LINK_ID擡頭,所以此列需要索引 。同樣,RDF_NODE需要NODE_ID的索引,但這些索引已經存在。)