我应该使用多列索引还是两个1列?

时间:2013-04-07 07:42:35

标签: sql sqlite

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

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约束创建索引。

2 个答案:

答案 0 :(得分:1)

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

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

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

但是,然后再次,优化器可以根据可用的表和索引统计信息选择不同的路径。

希望这有帮助。

答案 1 :(得分: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)

另见文件:
Query Optimizer Overview
Query Planning