sql - 如何优化 SQLite ORDER BY rowid?

标签 sql sqlite sorting

我想在我的 sqlite 数据库中查询所有大于 20 的“级别”值,将结果限制为 100 并按 rowid 排序。

按 rowid 排序时,查询会慢很多。该数据库包含约 300 万条记录 level的最大值为50,为level创建索引。

此语句耗时约 20 毫秒:

SELECT * FROM log WHERE level > 20 LIMIT 100

此语句耗时约 100 毫秒:

SELECT * FROM log WHERE level > 20 ORDER BY rowid LIMIT 100

此语句耗时约 1000 毫秒(不存在级别值大于 50 的行):

SELECT * FROM log WHERE level > 50 ORDER BY rowid LIMIT 100

有没有办法优化它以获得更快的 ORDER BY 查询?

这是使用的索引:

CREATE INDEX level_idx ON table (level)

最佳答案

有两种可能的方法来执行这个查询:

  1. level_idx 索引中搜索具有 level>20 的第一个条目,然后扫描所有后续条目并从表中获取每个相应的行。 由于索引条目未按 rowid 顺序存储,因此必须对所有结果进行排序。 然后可以返回其中的前 100 个。

  2. 忽略索引。 扫描表的所有行(已按 rowid 顺序存储),并返回与 level 列匹配的任何行。

数据库估计第二种方法更快。

如果您估计第一种方法更快,即只有很少的行匹配 level 过滤器,那么获取和排序剩余行比在扫描时忽略不匹配的行更快表,那么你可以强制数据库使用带有 INDEXED BY 子句的索引:

SELECT *
FROM log INDEXED BY level_idx
WHERE level > 20
ORDER BY rowid
LIMIT 100

但是,如果您自己的估计是错误的,强制索引可能会导致可怕的减速。

关于sql - 如何优化 SQLite ORDER BY rowid?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24188826/

相关文章:

sql - 如何在 postgres 中的文本列上添加唯一约束(忽略特殊字符)?

sql - 如何在 Hive 0.13.1 中使用 CSV 数据分解字符串列

android - 更新查询在 Android 中不起作用

Python SQLite : Update Statement TypeError: function takes exactly 2 arguments (1 given)

在 golang 中排序

mysql - 删除 varchar 中的逗号以获取数字并测试

php - Pdo 未定义索引和无效参数号

multithreading - 带有Qt的SQLite3中的“Database is locked”错误

c++ - 使用不同容器、C++、STL 进行排序和查询

actionscript-3 - 在ActionScript 3中对对象数组进行排序