如何关闭 SQLite 自动索引功能?

how to turn off SQLite autoindex feature?

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

问题: 是在应用程序创建数据库时 - SQLite 自动向数据库中的某些字段添加索引。他们叫 sqlite_autoindex_%TableName%%ColumnName%_1

我的 ORM 实体具有标记为在数据库中建立索引的字段。在创建表之后,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;
}

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

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

与几乎总是声明的不同,您可以不生成自动索引,这可能会显着减少数据库大小(根据自己的经验)。

根据我自己的经验,当您有 table 和 "ROWID" 时,您会得到 sqlite_autoindex_"table_name"_N,这是默认设置。如果您使用 WITHOUT ROWID [synax] 设计 table,则该 table 不再有自动索引(连同 "ROWID")。

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

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

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

作为旁注,以帮助避免与 SQLite 中术语“自动索引”的另一种用法混淆,请注意 [source]:

Do not confuse automatic indexes with the internal indexes (having names like "sqlite_autoindex_table_N") that are sometimes created to implement a PRIMARY KEY constraint or UNIQUE constraint. The automatic indexes described here exist only for the duration of a single query, are never persisted to disk, and are only visible to a single database connection. Internal indexes are part of the implementation of PRIMARY KEY and UNIQUE constraints, are long-lasting and persisted to disk, and are visible to all database connections. The term "autoindex" appears in the names of internal indexes for legacy reasons and does not indicate that internal indexes and automatic indexes are related.

形式上,用SQLite,自动索引,真的有别的意思。这种混淆也无济于事,看官方文档一定要注意。

这个在 Ormlite 和 Sqlcipher 中对我有用:

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