何时在 SQLite 中创建多列索引?

When to create multi-column indices in SQLite?

假设我在 SQLite 数据库中有一个 table:

CREATE TABLE orders (
    id INTEGER PRIMARY KEY,
    price INTEGER NOT NULL,
    updateTime INTEGER NOT NULL,
) [WITHOUT ROWID];

我应该创建什么索引来优化以下查询:

SELECT * FROM orders WHERE price > ? ORDER BY updateTime DESC;

我是否创建两个索引:

CREATE INDEX i_1 ON orders(price);
CREATE INDEX i_2 ON orders(updateTime);

还是一个复杂索引?

CREATE INDEX i_3 ON orders(price, updateTime);

什么是查询时间复杂度?

来自The SQLite Query Optimizer Overview/WHERE Clause Analysis

If an index is created using a statement like this:

CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z);

Then the index might be used if the initial columns of the index (columns a, b, and so forth) appear in WHERE clause terms. The initial columns of the index must be used with the = or IN or IS operators. The right-most column that is used can employ inequalities.

The SQLite Query Optimizer Overview/The Skip-Scan Optimization 中的示例所述:

Because the left-most column of the index does not appear in the WHERE clause of the query, one is tempted to conclude that the index is not usable here. However, SQLite is able to use the index.

这意味着如果您创建如下索引:

CREATE INDEX idx_orders ON orders(updateTime, price);

可能 用于优化 WHERE 子句,即使 updateTime 没有出现在那里。

此外,来自 The SQLite Query Optimizer Overview/ORDER BY Optimizations

SQLite attempts to use an index to satisfy the ORDER BY clause of a query when possible. When faced with the choice of using an index to satisfy WHERE clause constraints or satisfying an ORDER BY clause, SQLite does the same cost analysis described above and chooses the index that it believes will result in the fastest answer.

由于updateTime首先在复合索引中定义,索引也可以用于优化ORDER BY子句。