如何优化SQLite ORDER BY rowid?

时间:2014-06-12 15:56:46

标签: sql sqlite sorting

我想查询我的sqlite数据库以查找所有" level"大于20的值,将结果限制为100并按rowid排序。

按rowid排序时,查询速度要慢得多。该数据库包含约300万条记录 并且level的最大值为50.为level创建索引。

此语句需要大约20ms:

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 个答案:

答案 0 :(得分:6)

执行此查询有两种可能的方法:

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

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

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

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

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

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