FTS数据库优化(Android)原理与应用详解(2)

xiaoxiao2021-02-27  385

3.在Android上FTS优化效果如何?——Android官方demo性能评测

接下来的问题就是FTS的优化效果如何了。先在Android官方demo的基础上做一些测试。demo中数据库是一个英文字典,单词条目998。Android/SQLite数据库本身的性能已经足够强悍,在这个量级下显然看不出差异。将数据规模扩大5000倍,即将998条数据循环插入数据库5000次:4990000。这个数据库规模已经远超牛津大辞典,据说牛津大辞典第二版一共有25万英文单词。与FTS PK的是一般的数据库表,同样只有两个字段。创建数据库代码:

private static final String FTS_TABLE_CREATE = "CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE + " USING fts3 (" + KEY_WORD + ", " + KEY_DEFINITION + ");"; private static final String NO_FTS_TABLE_CREATE = "CREATE TABLE " + NO_FTS_VIRTUAL_TABLE + " (" + KEY_WORD + " TEXT, " + KEY_DEFINITION + " TEXT);"; @Override public void onCreate(SQLiteDatabase db) { Log.i(TAG, "DictionaryOpenHelper.onCreate()"); mDatabase = db; if (fts) { mDatabase.execSQL(FTS_TABLE_CREATE); loadDictionary(); } else { mDatabase.execSQL(NO_FTS_TABLE_CREATE); loadDictionary2(); } }

loadDictionary()/loadDictionary2()分别将4990000条数据插入到FTS virtual table和一般table。再看一下query的逻辑,MATCH vs LIKE:

/** * Returns a Cursor over all words that match the given query * * @param query The string to search for * @param columns The columns to include, if null then all are included * @return Cursor over all words that match, or null if none found. */ public Cursor getWordMatches(String query, String[] columns) { if (TextUtils.isEmpty(query)) { Log.i(TAG, "getWordMatches() : query is empty. return null."); return null; } if (fts) { String selection = KEY_WORD + " MATCH ?"; String[] selectionArgs = new String[]{query + "*"}; return query(selection, selectionArgs, columns); } else { String selection = KEY_WORD + " LIKE ?"; String[] selectionArgs = new String[]{query + "%"}; return query(selection, selectionArgs, columns); } } 先比对一下数据库的大小(db文件):

fts virtual table:647M

一般table:364.2M

可以看到FTS会造成数据库文件明显的膨胀。

再来比对一下数据库查询速度。因为不同的手机硬件配置不同,所以速度的绝对值无意义,只在相同的数据集合上做同样的query,耗时对比。

查询关键字FTS DB普通 DBa5645ms4396msb2678ms3931msg2749ms3874mscons(consumer前半部分)2003ms3938msconsumer(完整单词)165ms3807msprof(profile前半部分)998ms3880msprofile(完整单词)163ms3804ms

可以看到,整体上优化效果还是很明显的。相对比,发现

(1)query"a"的时候,FTS表现不佳,之后有明显优势。从结果集数量上看,"a"召回结果最多,"b""g"次之。

(2)就FTS的优势而言,单个字母<部分单词<整个单词,整个单词的query就已经有巨大的优势了。

但这对于普通DB并不公平,普通DB没有创建索引,增加索引再看看:

查询关键字FTS DB普通 DB普通DB+Indexa5645ms4396ms4232msb2678ms3931ms3892msg2749ms3874ms3864mscons(consumer前半部分)2003ms3938ms3903msconsumer(完整单词)165ms3807ms3799msprof(profile前半部分)998ms3880ms3862msprofile(完整单词)163ms3804ms3798ms

看到在这个测试数据集,普通DB+index提升不大。

那么引出一些问题:

(1)为什么FTS会有上述表现?

(2)普通DB的index为什么有上述表现?

本文接下来会先探究一下FTS。普通DB会再其他文章中继续研究。

转载请注明原文地址: https://www.6miu.com/read-1328.html

最新回复(0)