SQLite连接优化

时间:2010-11-15 10:34:40

标签: sql sqlite indexing query-optimization

如果您有查询,例如:

select a.Name, a.Description from a
inner join b on a.id1 = b.id1
inner join c on b.id2 = c.id2
group by a.Name, a.Description

如果您认为每个表中有超过100,000行,那么在SQLite中为此查询编制索引的最佳列是什么?

我问的原因是,当我应用相同的优化时,我不会通过我期望从另一个RDBMS(SQL Server)获得与该组的查询的性能。

我是否正确地认为在SQLite查询中的单个表上引用的所有列都需要包含在单个复合索引中以获得最佳性能?

5 个答案:

答案 0 :(得分:5)

问题在于您希望SQLite具有与完整RDBMS相同的性能特征。它不会。 SQLLite没有足够的内容缓存,每次运行应用程序时都需要重建缓存,可能仅限于设置内核数量等等。使用嵌入式RDBMS的权衡一整个。

就优化而言,尝试索引查找列并进行测试。然后尝试创建覆盖索引。一定要测试selects和更新数据库的代码路径,你要加速另一个,而不是另一个。找到能够根据您的需求在两者之间取得最佳平衡的索引并继续使用。

答案 1 :(得分:3)

来自SQLite query optimization overview

在对行进行索引查找时,通常的做法是对索引进行二进制搜索以查找索引条目,然后从索引中提取rowid并使用该rowid进行二进制搜索原表。因此,典型的索引查找涉及两个二进制搜索。但是,如果从表中获取的所有列都已在索引本身中可用,则SQLite将使用索引中包含的值,并且永远不会查找原始表行。这为每行保存了一个二进制搜索,并且可以使许多查询运行速度提高两倍。

对于任何其他RDBMS,我会说在b.id1和c.id2上放置一个聚簇索引。对于SQLite,您可能最好包括要在这些索引中查找的b和c中的任何列。

答案 2 :(得分:1)

注意:我对SQLite及其执行计划的可能复杂性一无所知。

您肯定需要a.id1b.id1b.id2c.id2上的索引。我认为复合索引(b.id1, b.id2)可以产生小的性能提升。 (a.id1, a.Name, a.Description)也是如此。

答案 3 :(得分:1)

由于您没有将其他表用于返回列,因此这可能会更快:

SELECT DISTINCT a.Name, a.Description
FROM a, b, c
WHERE a.id1 = b.id1
AND b.id2 = c.id2

查看返回的列,因为标准似乎只是必须从a链接到bc,因此您可以查找所有唯一{{1} }和a.Name对。

a.Description

或者,根据每一对SELECT DISTINCT a.Name, a.Description FROM a WHERE a.id1 IN ( SELECT b.id1 FROM b WHERE b.id2 IN ( SELECT c.id2 FROM c ) ) a.Name是否已经是唯一的,首先找出唯一ID然后获取其他列应该会有所收获。

a.Description

答案 4 :(得分:0)

我认为a.id1和b.id2上的索引会给你带来与JOIN相同的好处。但SQLite提供了EXPLAIN,它可以帮助您确定当前执行计划中的效率是否可以避免。