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

时间:2015-02-19 17:23:00

标签: android sqlite ormlite

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

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

我的ORM entites标记了要在db中编入索引的字段。在创建表之后,ORMLite会创建索引。 SQLIte自动索引由ORMLIte创建的dublicates索引,因此我需要配置SQLite以关闭自动索引。 我发现此功能会在查询" PRAGMA automatic_index = false;"所以我重写了OrmLiteSqliteOpenHelper

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

那没有用。错误的查询地点? 请帮忙

3 个答案:

答案 0 :(得分:4)

与接近总是陈述的内容不同,您可以在不生成自动索引的情况下使用,这可能会显着减少数据库大小(在自己的经验之后)。

根据我自己的经验,当你有“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约束的实现的一部分,是持久的并且持久化到磁盘,并且对所有数据库连接都是可见的。 由于遗留原因,术语“autoindex”出现在内部索引的名称中,并不表示内部索引和自动索引是相关的。

正式地,使用SQLite,自动索引,实际上意味着别的东西。这种混淆没有帮助,在阅读官方文档时必须牢记这一点。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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