我在Android上使用SQLiteDatabase(http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)
使用SQLite我正在开发一个圣经应用程序,它有一个包含以下列的表:
每个句子被分解为一系列strongId /单词对,因此wordIdx用于对单词进行排序,strongId只是一个索引到一个索引,而单词是句子中的单词。
所以我有300,000行 瓶颈似乎是我查询每个经文的单词列表:
我的SQL实际上是这样的:
SELECT strongId, word FROM ? WHERE book=? AND chapter=? AND verse=?
以下是代码:
Cursor cursor = mBible.database().rawQuery("SELECT " + KEY_STRONGID + "," + KEY_WORD + " FROM " + tableName() + " WHERE " + KEY_BOOK + "=? AND " + KEY_CHAPTER + "=? AND " + KEY_VERSE + "=?" , new String[] { String.valueOf(mChapter.mBook.index()), String.valueOf(mChapter.index()), String.valueOf(verse) });
cursor.moveToFirst();
mWordList = new ArrayList<Word>();
do {
mWordList.add(new Word(cursor.getString(1), cursor.getString(0)));
} while (cursor.moveToNext());
现在,我已经尝试将每一章放入其自己的临时视图(使用CREATE TEMP VIEW),在我的示例中将记录减少到大约400,但仍然需要很长时间才能查询
以30秒的顺序生成两个章节的文本以显示给用户(使用临时视图而不使用临时视图)。如果我设置一个虚拟的单词列表以避免数据库查询,则大约需要5秒钟。
如何改善这种性能?似乎临时观点对我的表现没有影响。
答案 0 :(得分:1)
视图不会改变查询的性能;它只保存查询本身,而不是查询的结果。
如果您使用桌面计算机上的sqlite3
命令行工具打开数据库,则可以使用EXPLAIN QUERY PLAN command检查查询的效率。
没有任何索引,您查询始终扫描整个表:
> sqlite3 bible.db
SQLite version 3.7.15.2 2013-01-09 11:53:05
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> EXPLAIN QUERY PLAN SELECT strongId, word FROM MyTable WHERE book=1 AND chapter=2 AND verse=3;
0|0|0|SCAN TABLE MyTable (~1000 rows)
使用三个查找字段的索引,SQLite可以在索引中进行快速搜索,并且只需要从表中读取匹配的记录:
sqlite> CREATE INDEX b_c_v ON MyTable(book, chapter, verse);
sqlite> EXPLAIN QUERY PLAN SELECT strongId, word FROM MyTable WHERE book=1 AND chapter=2 AND verse=3;
0|0|0|SEARCH TABLE MyTable USING INDEX b_c_v (book=? AND chapter=? AND verse=?) (~8 rows)
如果您创建覆盖索引(在查询中使用所有字段,首先查找字段),SQLite根本不需要从表中读取。但是,这并没有比普通索引提供更大的加速,并且可能不值得额外的存储成本:
sqlite> CREATE INDEX cov ON MyTable(book, chapter, verse, strongId, word);
sqlite> EXPLAIN QUERY PLAN SELECT strongId, word FROM MyTable WHERE book=1 AND chapter=2 AND verse=3;
0|0|0|SEARCH TABLE MyTable USING COVERING INDEX cov (book=? AND chapter=? AND verse=?) (~8 rows)
请注意,SQLite在查询中每个表最多只能使用一个索引,因此创建多个索引并不总是有意义的。 使用EXPLAIN QUERY PLAN检查实际使用的索引,以及是否可以创建一些索引来优化大多数查询。
另请参阅Query Planning文档。
答案 1 :(得分:0)
我最终创建了临时表,现在可以接受性能