SQLite同步单&多列索引

时间:2018-02-13 06:55:32

标签: sqlite indexing

考虑SQLite表

CREATE TABLE IF NOT EXISTS tracer 
(
 bid INTEGER,
 sid INTEGER,
 ...
);

我通常想要运行带有

形式的查询
Q1 = SELECT * FROM tracer WHERE bid = 'bid_value';
Q2 = SELECT * FROM tracer WHERE sid = 'sid_value';
Q3 = SELECT * FROM tracer WHERE bid = 'bid_value' AND sid = 'sid_value';

现在假设我有索引

I1 = CREATE INDEX IF NOT EXISTS ibid ON tracer (bid);
I2 = CREATE INDEX IF NOT EXISTS isid ON tracer (sid);
I3 = CREATE INDEX IF NOT EXISTS ibidsid ON tracer (bid,sid);

我的理解是

  • 查询 Q1 SQLite将使用索引 I1
  • 查询 Q2 SQLite将使用索引 I2
  • 查询 Q3 SQLite将使用索引 I3

没有索引 I3 我认为查询 Q3 将运行得更慢,因为其他两个索引将按顺序用于查找选择结果。

但是,我认为这是有代价的 - 用额外的索引来扩大SQLite数据库文件的大小。我的问题 - 在决定是否使用covering indices(例如 I3 )进行索引时,如何估算对尺寸的影响?一些实证检验肯定能够说明发生了什么,但也许有更正式的方法来预测这些事情?

我应该提一下,这里的上下文是Android和iOS的移动应用程序。

我真的关心我的查询运行得更快吗?不是为了向用户呈现结果。但是,我确实担心应用程序在响应推送通知时运行SQL点时可能花费多少时间。我可以想象一个应用程序在后台运行时通过CPU资源占用过多被认为是一个坏公民。但是再次有一个权衡 - 由于其覆盖指数可能会使用更少的CPU,但覆盖指数会使其内存占用更大?

1 个答案:

答案 0 :(得分:0)

I3不是覆盖索引,因为查询必须读取其他列。

I1是多余的,因为使用bid的搜索也可以通过I3完成(请参阅query optimizer docs)。

更改表时,其他索引需要更多处理,但是当您读取少量行时,它们可能不会显着影响内存使用量。 (但如果你想确定,请测量。)

如果您的SQLite版本足够现代(即,可能不在移动设备上),您可以考虑使用clustered index