SQLITE 使用 ORDER BY 非常慢

Mik*_*e.M 8 database sqlite sorting performance

我有一个简单的查询,例如

SELECT * FROM "mytable" where col1="foo"
Run Code Online (Sandbox Code Playgroud)

大约 0.5 秒内即可解析(700 MB 数据库文件的约 100'000 行的约 100 个结果)

然而,我一添加就ORDER BY需要120秒。

SELECT * FROM "mytable" where col1="foo" ORDER BY col2
Run Code Online (Sandbox Code Playgroud)

即使我像这样限制结果

SELECT * FROM (SELECT * FROM "mytable" where col1="foo" LIMIT 1) ORDER BY col2
Run Code Online (Sandbox Code Playgroud)

尽管实际上没有什么可排序的,但它需要 120 秒。

唯一的例外是如果我使用ORDER BY rowid(而不是ORDER BY col2)排序,或者当我这样做时(0.5秒):

SELECT * FROM "mytable" WHERE rowid IN (SELECT rowid FROM "mytable"  WHERE col1="foo") ORDER BY col2
Run Code Online (Sandbox Code Playgroud)

VACUUM检查了数据库并检查了数据库的完整性(好的),但这个问题仍然存在。我正在使用 SQLite 版本:3.7.7.1,速度下降出现在 phpLITEadmin 和我的 PHP 代码中。

编辑

EXPLAIN QUERY PLAN SELECT * FROM "mytable" WHERE col1="foo" 
Run Code Online (Sandbox Code Playgroud)
selectid|订单|来自|详细信息
       0| 0| 0|扫描表 mytable (~11345 行)
EXPLAIN QUERY PLAN SELECT * FROM "mytable" WHERE col1="foo" ORDER BY col2
Run Code Online (Sandbox Code Playgroud)
selectid|订单|来自|详细信息
       0| 0| 0|使用自动覆盖索引搜索表 mytable (col1=?)(~7 行)
       0| 0| 0|使用临时 B 树进行排序

rus*_*tyx 5

因此,SQLite 似乎错误地认为构建临时索引(自动覆盖索引)来运行查询而不是在内存中排序会更便宜。显然,为每个查询建立 100,000 行索引并不是最优的查询计划。

一个明显的解决方案是在要执行查询/排序的列上添加索引。

CREATE INDEX col1_idx ON mytable (col1);
CREATE INDEX col2_idx ON mytable (col2);
Run Code Online (Sandbox Code Playgroud)

  • @Mike.M 也在 `col1` 上? (4认同)
  • 不,col1 没有任何索引,创建索引似乎解决了这个问题,或者我应该说,规避了这个 SQLITE 错误。谢谢。 (3认同)