0

我有一个表,我目前定义如下:

CREATE TABLE pairs (  
id INTEGER PRIMARY KEY,
p1 INTEGER,
p2 INTEGER,
r  INTEGER,
UNIQUE(p1, p2) ON CONFLICT IGNORE,
FOREIGN KEY (p1) REFERENCES points(id),
FOREIGN KEY (p2) REFERENCES points(id)
)

之后,它充满了千兆字节的数据。现在我需要像这样做很多选择:

SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666

所以问题是:我应该创建哪些索引来加速这个选择?

CREATE INDEX p1_index ON pairs(p1)
CREATE INDEX p2_index ON pairs(p2)

或者可能

CREATE UNIQUE INDEX p_index ON pairs(p1, p2)

或者可能两者兼而有之?(并为他们购买新的硬盘)。SQLite3 不会为UNIQUE多列的约束自动创建索引。

4

2 回答 2

2

由于您使用的是 OR 条件,因此我将使用多个索引。如果它是 AND 条件,那么多列索引会更好。

对于 OR 条件:优化器将开始查看其中一个索引,找到匹配项并抓取该行。仅当与第一个索引不匹配时,才会查看另一个索引。在多处理器系统上,两个索引也将(应该)并行扫描。太棒了,对吧?

对于 AND 条件:如果有 2 个索引可用,优化器将必须查看它们,合并两个索引扫描的输出,然后从基表中获取结果。这可能会变得很昂贵。在这里,多列索引会很棒。

但是话又说回来,优化器可能会根据可用的表和索引统计信息选择不同的路径。

希望这可以帮助。

于 2013-04-07T07:48:16.410 回答
0

使用EXPLAIN QUERY PLAN检查是否使用了索引。

对于您的示例查询,将使用两个单列索引:

> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX p1_index (p1=?) (~10 rows)
0|0|0|SEARCH TABLE pairs USING INDEX p2_index (p2=?) (~10 rows)

如果单个记录的查找需要两列,则将使用多列索引(由于 UNIQUE 约束您已经拥有):

> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 AND p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX sqlite_autoindex_pairs_1 (p1=? AND p2=?) (~1 rows)

但是,多列索引也可用于在其第一列上进行查找:

> DROP INDEX p1_index;
> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX sqlite_autoindex_pairs_1 (p1=?) (~10 rows)
0|0|0|SEARCH TABLE pairs USING INDEX p2_index (p2=?) (~10 rows)

另请参阅文档:
查询优化器概述
查询计划

于 2013-04-07T09:57:53.327 回答