我正在SQLite中测试一些查询性能,所以查看查询计划等。我遇到了这个(对我来说)有趣的场景,其中select count(*)
列出了索引作为覆盖索引,而使用{select *
相同的查询条件{1}}使用相同的索引,但不会将其列为覆盖索引。
有问题的查询和结果:
sqlite> explain query plan select count(*) from Table1 cross join Table2 on Table1.Id = Table2.Id and Table1.ExportTime >= Table2.InsertTime;
0|0|0|SCAN TABLE Table1 (~5000 rows)
0|1|1|SEARCH TABLE Table2 USING COVERING INDEX test_2 (Id=? AND InsertTime<?) (~167 rows)
sqlite> explain query plan select * from Table1 cross join Table2 on Table1.Id = Table2.Id and Table1.ExportTime >= Table2.InsertTime;
0|0|0|SCAN TABLE Table1 (~5000 rows)
0|1|1|SEARCH TABLE Table2 USING INDEX test_2 (Id=? AND InsertTime<?) (~167 rows)
为什么会这样?
答案 0 :(得分:3)
覆盖索引是一种索引,可用于解析整个查询,因此无需读取表。使用select *
查询,有必要读取表以检索列值。使用select count(*)
,它只能通过索引找到结果(计数)。