2016-07-29 23 views
1

創建一個表可以SQLite的`爲了by`和`where`子句中使用索引一起

CREATE TABLE Shares(
    shareId TEXT PRIMARY KEY NOT NULL, 
    fromId INTEGER NOT NULL, 
    toId INTEGER NOT NULL, 
    time INTEGER NOT NULL); 

,並創建索引

CREATE INDEX Shares_time_toId_fromId ON Shares(time, toId, fromId); 

然後插入一些行

insert into Shares(shareId, fromId, toId, time) values(1,1,1,1); 
insert into Shares(shareId, fromId, toId, time) values(2,2,2,2); 
insert into Shares(shareId, fromId, toId, time) values(3,3,3,3); 
insert into Shares(shareId, fromId, toId, time) values(4,3,3,4); 
insert into Shares(shareId, fromId, toId, time) values(5,3,3,5); 

用解釋來展示

explain select * from Shares where toId=3 and fromId=3 order by time desc; 

結果是

0|Init|0|20|0||00| 
1|Noop|0|0|0||00| 
2|OpenRead|0|2|0|4|00| 
3|OpenRead|2|4|0|k(4,nil,nil,nil,nil)|00| 
4|Last|2|17|1|0|00| 
5|IdxRowid|2|1|0||00| 
6|Seek|0|1|0||00| 
7|Column|2|1|2||00| 
8|Ne|3|16|2|(BINARY)|54| 
9|Column|2|2|4||00| 
10|Ne|3|16|4|(BINARY)|54| 
11|Column|0|0|5||00| 
12|Copy|4|6|0||00| 
13|Copy|2|7|0||00| 
14|Column|2|0|8||00| 
15|ResultRow|5|4|0||00| 
16|Prev|2|5|0||01| 
17|Close|0|0|0||00| 
18|Close|2|0|0||00| 
19|Halt|0|0|0||00| 
20|Transaction|0|0|2|0|01| 
21|TableLock|0|2|0|Shares|00| 
22|Integer|3|3|0||00| 
23|Goto|0|1|0||00| 

看來查詢使用索引來完成這項工作。但我不知道它是使用全部三個索引還是僅僅使用時間來完成索引。 我希望這些指數可以全部用於提升性能。

回答

3

要找出查詢是如何執行的,不使用EXPLAIN但EXPLAIN QUERY PLAN

explain query plan select * from Shares where toId=3 and fromId=3 order by time desc; 
0|0|0|SCAN TABLE Shares USING INDEX Shares_time_toId_fromId 

在此查詢中,toIdfromId值從指數看,但是這並不重要,因爲實際的表必須被讀取以獲得shareId的值。

如果查詢沒嘗試讀取shareId列,或者如果shareId列有型INTEGER因此,這將是對rowid的別名,因此是指數的一部分,單獨的表查找步驟也不會需要。

(注:latestsqlite3工具格式化EXPLAIN輸出更好。)

+0

感謝您的回答。如果我將主鍵更改爲單獨的'id INTEGER PRIMARY KEY'和'shareId TEXT NOT NULL'。這將有效地獲取rowid? – Naryc

+0

那麼'shareId'會成爲索引的一部分嗎? –

+0

不,因爲我認爲查詢使用'time''Id'' fromId'來獲取索引條目。然後使用Index中的rowid來查找數據庫中的整個行。所以shareId不能成爲索引的一部分。我對嗎? – Naryc

相關問題