2015-01-14 38 views
1

我執行上的SQLite查詢和計劃的一部分是我如何理解sqlite查詢計劃?

0|1|5|SCAN TABLE edges AS e1 (~250000 rows) 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 
2|0|0|SEARCH TABLE dihedral USING AUTOMATIC 
COVERING INDEX (TYPE=? AND EDGE=?) (~7 rows) 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 3 
3|0|0|SEARCH TABLE bounds USING AUTOMATIC 
COVERING INDEX (FACE=? AND EDGE=?) (~7 rows) 

,其中在其中

exists (select dihedral.edge from dihedral where ihedral.type=2 and dihedral.edge=e1.edge) and 
exists (select bounds.edge from bounds where bounds.face=f1.face and bounds.edge=e1.edge) and 

我明白這不是一個系列高效查詢,Ijust查詢想要提高性能。

這是我的猜想:

  1. 沒有子查詢展平,對不對?

  2. 兩個存在的子查詢引入了相關的子查詢,並且當它們被作爲索引嵌套循環執行時,對嗎?

  3. 閱讀查詢,因爲表二面角和邊界是獨立的,都與外邊緣表相關,所以計算複雜度爲O(n^2)沒有索引。但是,由於有覆蓋指數,表現應該好多了,對吧?我在維基上發現,索引的性能爲O(log(N))甚至更​​好,所以整體性能應該是O(n*log(N)),對不對?

任何人都可以幫助我瞭解發生了什麼?謝謝。

回答

0

SQLite確實支持subquery flattening,但這不可能像這樣的EXISTS子查詢。

AUTOMATIC顯示數據庫僅爲該查詢創建臨時索引。 這是你要永久創建這些指標強烈暗示:

CREATE INDEX dihedral_type_edge ON dihedral(type, edge); 
CREATE INDEX bounds_face_edge ON bounds(face, edge); 

外部查詢遍歷所有edge行,每一行,在索引搜索。 這將導致O(edge * (log(dihedral) + log(bounds)))。 創建臨時索引需要對這些表進行排序,因此整個運行時間結束爲O(dihedral*log(dihedral) + bounds*log(bounds) + edge*(log(dihedral)+log(bounds)))

+0

謝謝,這很清楚。在我的示例中,還有另一個子句'0 | 0 | 0 | SCAN TABLE faces AS f1(〜500000 rows)0 | 1 | 5 |掃描表邊緣AS e1(〜250000行)3 | 0 | 0 | SEARCH TABLE bounds使用自動覆蓋索引(FACE =?和EDGE =?)(~7行)'如何估計它的順序? – user3329081

+0

編輯問題以顯示完整的計劃。 –