Sqlite视图不对左联接查询使用索引
在Sqlite中,我将视图定义为两个表的联合。当我使用该视图运行查询时,如果查询足够简单,就会使用索引。对于某些复杂的查询,它不会这样做,并最终运行完整的表扫描。有什么方法可以有效地使用视图吗 表/视图定义: 简单查询(使用索引): 解释查询计划:Sqlite视图不对左联接查询使用索引,sqlite,indexing,view,union,Sqlite,Indexing,View,Union,在Sqlite中,我将视图定义为两个表的联合。当我使用该视图运行查询时,如果查询足够简单,就会使用索引。对于某些复杂的查询,它不会这样做,并最终运行完整的表扫描。有什么方法可以有效地使用视图吗 表/视图定义: 简单查询(使用索引): 解释查询计划: 复合查询 最左侧子查询 使用索引sqlite\u autoindex\u Table1\u 1(Id=?)将表1搜索为T1 联合所有 使用索引sqlite\u autoindex\u Table2\u 1(Id=?)将表2搜索为T2 左联接查询(不使
Table1
和Table2
进行完整的表扫描,因为您没有对UnionView
进行任何筛选它确实使用了sqlite\u autoindex\u Table3\u 1
此外,
WHERE
子句在联接之后应用
如果在加入之前筛选UnionView,则将使用索引:
EXPLAIN QUERY PLAN
SELECT T3.Id
FROM [Table3] T3
LEFT JOIN (SELECT Id FROM [UnionView] WHERE Id = 'asdf') T
ON T3.Id=T.Id
WHERE T3.Id = 'asdf'
结果:
- 具体化3
- 复合查询
- 最左侧子查询
- 使用索引sqlite\u autoindex\u Table1\u 1(Id=?)将表1搜索为T1
- 联合所有
- 使用索引sqlite\u autoindex\u Table2\u 1(Id=?)将表2搜索为T2
- 使用覆盖索引sqlite\u autoindex\u Table3\u 1(Id=?)将表3搜索为T3
- 扫描子查询3
SELECT T3.Id FROM Table3 T3 LEFT JOIN Table1 T1 on T3.Id=T1.Id,其中T3.Id='asdf'
我相信我的困惑在于,因为在编写SELECT时我们可以将视图视为表,我不希望做一些不同的事情来高效地查询视图。@FernandoRodriguez不,这是不正确的。只有sqlite\u autoindex\u Table3\u 1
将用于该查询,因为同样只有T3被过滤。@FernandoRodriguez查看演示:好的,也许这更像是sqlite优化的抱怨,但是sqlite不应该认为Id过滤器也应该应用于UnionView,而不是强迫我复制过滤器吗?您确实提到了where子句是在连接之后执行的,这有助于解释该行为。@FernandoRodriguez否,任何SQL查询中执行语句的顺序都会首先应用带有ON子句的连接,然后应用where子句中的条件。
SELECT Id FROM [UnionView] WHERE Id = 'asdf'
SELECT T3.Id FROM [Table3] T3 LEFT JOIN [UnionView] T ON T3.Id=T.Id WHERE T3.Id = 'asdf'
EXPLAIN QUERY PLAN
SELECT T3.Id
FROM [Table3] T3
LEFT JOIN (SELECT Id FROM [UnionView] WHERE Id = 'asdf') T
ON T3.Id=T.Id
WHERE T3.Id = 'asdf'