And*_*ers 35 android android-contentresolver android-contentprovider
我正在开发一个应用程序,我需要插入大量的联系人条目.目前约有600个联系人,共有6000个电话号码.最大的联系人有1800个电话号码.
截至今天的状态是我创建了一个自定义帐户来保存联系人,因此用户可以选择在"联系人"视图中查看联系人.
但插入触点非常缓慢.我使用ContentResolver.applyBatch插入联系人.我尝试了不同大小的ContentProviderOperation列表(100,200,400),但总运行时间约为.相同.插入所有联系人和号码大约需要30分钟!
我发现在SQlite中缓慢插入的大多数问题都会导致交易.但是因为我使用ContentResolver.applyBatch方法,所以我不控制它,我会假设ContentResolver为我负责事务管理.
所以,我的问题是:我做错了什么,或者我能做些什么来加快这个速度?
安德斯
编辑: @jcwenger:哦,我明白了.很好的解释!
那么我将首先插入raw_contacts表,然后插入带有名称和数字的数据表.我将失去的是对我在applyBatch中使用的raw_id的后向引用.
所以我必须获取新插入的raw_contacts行的所有id作为数据表中的外键吗?
jcw*_*ger 51
用ContentResolver.bulkInsert (Uri url, ContentValues[] values)而不是ApplyBatch()
ApplyBatch(1)使用事务和(2)它为整个批处理锁定ContentProvider一次,而不是每次操作锁定/解锁一次.因此,它比一次一个(非批量)快一点.
但是,由于批处理中的每个操作都可以具有不同的URI等,因此会产生大量的开销."哦,一个新的操作!我想知道它进入了什么桌子......在这里,我将插入一行......哦,一个新的操作!我想知道它在哪个表格......"无限广告.由于将URI转换为表格的大部分工作涉及大量的字符串比较,因此它显然非常慢.
相比之下,bulkInsert将整堆值应用于同一个表.它说,"批量插入......找到桌子,好吧,插入!插入!插入!插入!插入!" 快多了.
当然,它需要您的ContentResolver有效地实现bulkInsert.大多数人都这样做,除非你自己写的,在这种情况下需要一些编码.
Vir*_*ren 10
bulkInsert:对于那些感兴趣的人,这是我能够试验的代码.注意我们如何避免int/long/floats的一些分配:)这可以节省更多时间.
private int doBulkInsertOptimised(Uri uri, ContentValues values[]) {
    long startTime = System.currentTimeMillis();
    long endTime = 0;
    //TimingInfo timingInfo = new TimingInfo(startTime);
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    DatabaseUtils.InsertHelper inserter =
        new DatabaseUtils.InsertHelper(db, Tables.GUYS); 
    // Get the numeric indexes for each of the columns that we're updating
    final int guiStrColumn = inserter.getColumnIndex(Guys.STRINGCOLUMNTYPE);
    final int guyDoubleColumn = inserter.getColumnIndex(Guys.DOUBLECOLUMNTYPE);
//...
    final int guyIntColumn = inserter.getColumnIndex(Guys.INTEGERCOLUMUNTYPE);
    db.beginTransaction();
    int numInserted = 0;
    try {
        int len = values.length;
        for (int i = 0; i < len; i++) {
            inserter.prepareForInsert();
            String guyID = (String)(values[i].get(Guys.GUY_ID)); 
            inserter.bind(guiStrColumn, guyID);
            // convert to double ourselves to save an allocation.
            double d = ((Number)(values[i].get(Guys.DOUBLECOLUMNTYPE))).doubleValue();
            inserter.bind(guyDoubleColumn, lat);
            // getting the raw Object and converting it int ourselves saves
            // an allocation (the alternative is ContentValues.getAsInt, which
            // returns a Integer object)
            int status = ((Number) values[i].get(Guys.INTEGERCOLUMUNTYPE)).intValue();
            inserter.bind(guyIntColumn, status);
            inserter.execute();
        }
        numInserted = len;
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
        inserter.close();
        endTime = System.currentTimeMillis();
        if (LOGV) {
            long timeTaken = (endTime - startTime);
            Log.v(TAG, "Time taken to insert " + values.length + " records was " + timeTaken + 
                    " milliseconds " + " or " + (timeTaken/1000) + "seconds");
        }
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return numInserted;
}
| 归档时间: | 
 | 
| 查看次数: | 19934 次 | 
| 最近记录: |