【问题标题】:how to turn off SQLite autoindex feature?如何关闭 SQLite 自动索引功能?
【发布时间】:2015-02-19 17:22:59
【问题描述】:

我的 Android 应用程序使用 SQLiteORMLite 来处理数据。需要一次插入大量数据,我想让这比现在更快。为此,我想删除索引,然后插入数据,然后重新创建索引。

问题: 是应用程序创建数据库时 - SQLite 会自动为 db 中的某些字段添加索引。他们打电话给sqlite_autoindex_%TableName%%ColumnName%_1

我的 ORM 实体具有标记为在 db 中索引的字段。在创建表之后,ORMLite 会创建该索引。 SQLIte 自动索引复制由 ORMLite 创建的索引,因此我需要配置 SQLite 以关闭自动索引。 我发现这个功能会在查询“PRAGMA automatic_index = false;”时关闭所以我覆盖了OrmLiteSqliteOpenHelper的方法:

@Override
public SQLiteDatabase getWritableDatabase() {
    SQLiteDatabase db = super.getWritableDatabase();
    db.execSQL("PRAGMA automatic_index = false;");
    return db;
}

这没有帮助。查询的地方不对? 请帮忙

【问题讨论】:

  • 你的架构是什么? IIRC SQLite 需要对 UNIQUE 列进行索引,并将自动为它们创建索引。 PRAGMA automatic_index 指的是an unrelated feature where SQLite will create a temporary index while evaluating a query
  • 我不知道如何获取架构信息。我认为这是主要的 sqlite 模式。自动索引不是临时的。我在 navicat 中打开了我的数据库,发现索引的类型为“正常”。
  • 犯了一个错误 :( 索引名为 sqlite_autoindex_%TableName%_1 没有列名。Navicat 显示它们没有任何列。

标签: android sqlite ormlite


【解决方案1】:

与通常所说的不同,您可以不生成自动索引,这可能会显着减少数据库大小(根据自己的经验)。

根据我自己的经验,当您有带有“ROWID”的表时,您会得到sqlite_autoindex_"table_name"_N,这是默认值。如果您使用WITHOUT ROWID [synax] 设计一个表,则该表将不再有自动索引(以及不再有“ROWID”)。

但是,请注意以下 [source]:

  • WITHOUT ROWID 表,不能使用AUTOINCREMENT
  • WITHOUT ROWID 表,必须有 PRIMARY KEY(为此,最好的办法是使用表行的前缀);
  • WITHOUT ROWID 表在 PK 值方面表现不同:SQLite 中曾经有一个错误,让它接受来自主键的 NULL 值(因此与标准不同)。后来,当添加WITHOUT ROWID 时,决定它还将强制执行标准语义,该语义不允许NULL 用于主键。

另外,根据我自己的经验,如果有任何UNIQUE 约束没有PK 作为前缀,sqlite_autoindex_"table_name"_N 仍然会生成(必须想象一个实现可能是什么,猜猜为什么就是这样)。

为了避免与 SQLite 中“自动索引”一词的其他用法混淆,请注意以下内容 [source]:

不要将自动索引与有时为实现 PRIMARY KEY 约束或 UNIQUE 约束而创建的内部索引(名称如“sqlite_autoindex_table_N”)混淆。此处描述的自动索引仅在单个查询期间存在,从不持久化到磁盘,并且仅对单个数据库连接可见。内部索引是 PRIMARY KEY 和 UNIQUE 约束实现的一部分,是持久的并持久化到磁盘上,并且对所有数据库连接都是可见的。 “自动索引”一词出于遗留原因出现在内部索引的名称中,并不表示内部索引和自动索引相关。

正式地说,对于 SQLite,自动索引确实意味着其他东西。这种混淆无济于事,阅读官方文档时必须牢记这一点。

【讨论】:

    【解决方案2】:

    SQLite 自动为 PRIMARY KEY 或 UNIQUE 约束中的列创建索引。 (唯一的例外是整数主键。) 这些不能被禁用。

    【讨论】:

      【解决方案3】:

      这个在 Ormlite 和 Sqlcipher 中适用于我:

      SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(...);
      database.rawExecSQL("PRAGMA automatic_index = 0"); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        • 2016-07-07
        • 2013-09-11
        • 2014-01-18
        • 2019-03-12
        • 1970-01-01
        相关资源
        最近更新 更多