Sqlite View 不使用索引进行左连接查询

Sqlite View does not use index for left join queries

在 Sqlite 中,我将视图定义为两个 table 的联合。当我 运行 使用该视图进行查询时,如果查询足够简单,则会使用索引。对于某些复杂的查询,它不会并最终 运行ning 完整 table 扫描。有没有办法解决这个问题,以便我可以高效地使用视图?

Table/View 定义:

CREATE TABLE 'Table1'     (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK,    Name varchar (255)    )
CREATE TABLE 'Table2'     (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK,    Name varchar (255)    )
CREATE TABLE 'Table3'     (Id varchar (18) PRIMARY KEY UNIQUE ON CONFLICT ROLLBACK,    Name varchar (255)    )
CREATE VIEW [UnionView] AS SELECT 'T1' tid, T1.rowid, T1.* FROM [Table1] T1 UNION ALL SELECT 'T2' tid, T2.rowid, T2.* FROM [Table2] T2

简单查询(使用索引):

SELECT Id FROM [UnionView] WHERE Id = 'asdf'

解释查询计划:

  1. 复合查询
  2. 最左子查询
  3. SEARCH TABLE Table1 AS T1 USING INDEX sqlite_autoindex_Table1_1 (Id=?)
  4. 联合所有
  5. SEARCH TABLE Table2 AS T2 USING INDEX sqlite_autoindex_Table2_1 (Id=?)

LEFT JOIN 查询(​​未使用索引):

SELECT T3.Id FROM [Table3] T3 LEFT JOIN [UnionView] T ON T3.Id=T.Id  WHERE T3.Id = 'asdf'

解释查询计划

  1. 实体化 2
  2. 复合查询
  3. 最左子查询
  4. 扫描 TABLE Table1 AS T1
  5. 联合所有
  6. 扫描TABLE Table2 AS T2
  7. SEARCH TABLE Table3 AS T3 USING COVERING INDEX sqlite_autoindex_Table3_1 (Id=?)
  8. 扫描子查询 2 为 T

您的 复杂 查询对 Table1Table2 进行了完整 table 扫描,因为您没有对 UnionView 进行任何过滤].
它确实使用 sqlite_autoindex_Table3_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
  • 复合查询
  • 最左子查询
  • SEARCH TABLE Table1 AS T1 USING INDEX sqlite_autoindex_Table1_1 (Id=?)
  • 联合所有
  • SEARCH TABLE Table2 AS T2 USING INDEX sqlite_autoindex_Table2_1 (Id=?)
  • SEARCH TABLE Table3 AS T3 USING COVERING INDEX sqlite_autoindex_Table3_1 (Id=?)
  • 扫描子查询 3