【问题标题】:Can sqlite `order by` and `where` clause use the Index togethersqlite `order by` 和 `where` 子句可以一起使用索引吗
【发布时间】:2016-07-29 07:43:59
【问题描述】:

创建表格

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|

查询似乎使用索引来完成工作。但我不知道它是使用所有三个索引还是只是使用时间来做索引。 我希望这些索引都可以用来提高性能。

【问题讨论】:

    标签: sql sqlite indexing sql-order-by


    【解决方案1】:

    要了解查询是如何执行的,不要使用 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 的别名并因此成为索引的一部分,则不需要单独的表查找步骤。

    (注意:sqlite3 工具的latest 版本可以更好地格式化 EXPLAIN 输出。)

    【讨论】:

    • 感谢您的回答。如果我将主键更改为单独的id INTEGER PRIMARY KEYshareId TEXT NOT NULL。这对获取 rowid 是否有效?
    • shareId 会成为索引的一部分吗?
    • 没有。正如我认为查询使用 time toId fromId 来获取索引条目。然后使用 Index 中的 rowid 来定位数据库中的整行。所以 shareId 不能成为索引的一部分。我说的对吗?
    • 是的。 (您可以将shareId 添加到索引中;但要衡量。)
    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    相关资源
    最近更新 更多