【问题标题】:SQLite: Optimize table scansSQLite:优化表扫描
【发布时间】:2011-09-25 16:53:32
【问题描述】:

在我的表中,有些列没有索引,在这些列中搜索值可能需要很长时间,因为 SQLite 会进行全表扫描。

在我的具体情况下,我正在寻找的行(值是唯一的)几乎总是在最近插入的行中。

我怀疑 SQLite 在进行扫描时从最旧(第一)行开始,有没有办法指示 SQLite 以相反的顺序进行表扫描?

更新:我在更新日志中找到了这个:

如果这样做满足 ORDER BY ... DESC 子句,优化器现在将反向扫描表。

所以也许这意味着我可以添加一个 ORDER BY 子句来加快速度。

【问题讨论】:

  • 按 DESC 排序不会导致 SQLite 在找到匹配项时停止扫描行。如果您的值在该列中是唯一的,它将继续扫描,在找到第一个匹配项后不会再找到其他匹配项。请参阅下面的 LIMIT 建议。

标签: sqlite optimization indexing full-table-scan


【解决方案1】:

解决办法是:

ORDER BY rowid DESC LIMIT 1

它使查找速度快如闪电!

【讨论】:

    【解决方案2】:

    扫描的顺序(从最老到最年轻或从最年轻到最老)无关紧要,因为需要进行全表扫描。必须访问每一行。尽管您提到了“我正在寻找的行”条件

                        .... where col = 'a'
    

    可能返回一行,也可能返回 10 行或 500 行。当遇到第一个匹配行时,SQLite 不能简单地停止并称其为美好的一天,除非您使用 LIMIT 指令。

    编辑:但是,您可以做的是使用时间戳列,对其进行索引,然后使用内联视图获取相对较新的行:

                  select * from
                  (
                   select * from T 
                   where datecreated > {somerecentdate}
                  ) as myView
                  where myView.someColumn = 'a'
    

    或者干脆

                select * from T where datecreated > {some date} and somecolumn = 'a'
    

    这种方法可能是一个迭代过程——如果没有返回任何行,您可能需要使用更宽的时间窗口重新查询。 但是,如果你要索引 datecreated,你不妨索引 [someColumn]。

    【讨论】:

    • 它总是返回一行,因为列中的值是唯一的。我不使用 UNIQUE 或 INDEX,因为它会减慢插入速度。我最初的想法是使用与您在上面描述的相同的迭代过程,甚至不需要额外的“datecreated”列,您只需在行的 id 上执行它,因为它们总是递增。但我希望有一个内置的解决方案,而不是自己实现智能算法。
    • 如果列没有被索引,它总是返回一行并不是 SQLite 可以知道的事实。始终需要进行全表扫描。如果有 LIMIT() 优化,您可以使用 LIMIT 1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多