[Android] 提高ORMLite插入大量數(shù)據(jù)效率的解決方案

問(wèn)題描述


在使用開(kāi)源ORMLite數(shù)據(jù)庫(kù)組件時(shí),為了測(cè)試需要,寫(xiě)了個(gè)異步任務(wù)循環(huán)生成10000條數(shù)據(jù),代碼如下:

/**
 * 創(chuàng)建數(shù)據(jù)測(cè)試數(shù)據(jù)
 * @author JacenChiu
 */
private class CreateTestDataForDb extends AsyncTask<Integer, Void, Long>{
    public int countPerTime = 10000;
    
    @Override
    protected void onPreExecute(){
        super.onPreExecute();
    }
    
    @Override
    protected Long doInBackground(Integer... params){
        long startTime = System.currentTimeMillis();
        for(int i=1; i<=10000; i++){
            ClaxxDao.createOrUpdate(new Claxx("測(cè)試班級(jí)" + i));
            Message message = new Message();
            message.what = 1;
            message.obj = i + "/" + countPerTime;
            mCreateProgressHandler.sendMessage(message);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
    
    @Override
    protected void onPostExecute(Long result){
        Message message = new Message();
        message.what = 1;
        message.obj = "耗時(shí)【" + (result/1000) + "】秒";
        mCreateProgressHandler.sendMessage(message);
        Toast.makeText(getApplicationContext(), 
            "創(chuàng)建數(shù)據(jù)完成翁垂,耗時(shí)【" + (result/1000) + "】秒!", Toast.LENGTH_LONG).show();
        Log.d("MainActivity", "--創(chuàng)建數(shù)據(jù)完成硝桩,耗時(shí)【" + (result/1000) + "】秒沿猜!");
        Intent intent = new Intent(Constant.ACTION_REFREASH_CLASS);
        mContext.sendBroadcast(intent);
        super.onPostExecute(result);
    }
}   

在GalaxyS4執(zhí)行上面的代碼,發(fā)現(xiàn)這1w條數(shù)據(jù)居然要耗時(shí)195s才完成碗脊,如下圖:


插入1w條數(shù)據(jù)耗時(shí)

原因分析


之所以會(huì)耗時(shí)那么久啼肩,是因?yàn)镺RMLite每次執(zhí)行ClaxxDao.createOrUpdate(new Claxx("測(cè)試班級(jí)" + i))時(shí)都會(huì)自動(dòng)提交數(shù)據(jù),而不是在最后統(tǒng)一提交數(shù)據(jù)的,這樣相當(dāng)于commit了1w次疟游。

如果要提高效率就必須關(guān)閉該DAO的自動(dòng)提交功能呼畸,并開(kāi)啟事務(wù)痕支,在所有數(shù)據(jù)的insert語(yǔ)句都生成后颁虐,統(tǒng)一一次commit。

解決方案


通過(guò)下面的ORM事務(wù)的代碼改造卧须,可以將1w條數(shù)據(jù)插入時(shí)間縮短到14s

/**
 * 創(chuàng)建數(shù)據(jù)測(cè)試數(shù)據(jù)
 * @author JacenChiu
 */
private class CreateTestDataForDb extends AsyncTask<Integer, Void, Long> {
    public int countPerTime = 10000;
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
    
    @Override
    protected Long doInBackground(Integer... params) {
        // ORMLite的數(shù)據(jù)連接封裝類(lèi)
        AndroidDatabaseConnection adc = null;
        adc = new AndroidDatabaseConnection(DatabaseHelper.getHelper().getWritableDatabase(), true);
        // 設(shè)置要開(kāi)啟事務(wù)的DAO不自動(dòng)提交代碼
        RuntimeExceptionDao<Claxx, String> dao = DatabaseHelper.getHelper().getClaxxDao();
        dao.setAutoCommit(adc, false);
        // 存儲(chǔ)點(diǎn)名稱(chēng)為create_claxx
        Savepoint sp = null;
        try {
            sp = adc.setSavePoint("create_claxx");
            long startTime = System.currentTimeMillis();
            for (int i = 1; i <= 10000; i++) {
                dao.createOrUpdate(new Claxx("測(cè)試班級(jí)" + i));
                Message message = new Message();
                message.what = 1;
                message.obj = i + "/" + countPerTime;
                mCreateProgressHandler.sendMessage(message);
            }
            // 成功添加后統(tǒng)一提交數(shù)據(jù)
            adc.commit(sp);
            long endTime = System.currentTimeMillis();
            return endTime - startTime;
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                // 發(fā)生異常時(shí)進(jìn)行回滾
                adc.rollback(sp);
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            return 0l;
        } 
    }
    
    @Override
    protected void onPostExecute(Long result) {
        Message message = new Message();
        message.what = 1;
        message.obj = "耗時(shí)【" + (result / 1000) + "】秒";
        mCreateProgressHandler.sendMessage(message);
        Toast.makeText(getApplicationContext(), 
            "創(chuàng)建數(shù)據(jù)完成另绩,耗時(shí)【" + (result / 1000) + "】秒!", Toast.LENGTH_LONG).show();
        Log.d("MainActivity", "--創(chuàng)建數(shù)據(jù)完成花嘶,耗時(shí)【" + (result / 1000) + "】秒笋籽!");
        Intent intent = new Intent(Constant.ACTION_REFREASH_CLASS);
        mContext.sendBroadcast(intent);
        super.onPostExecute(result);
    }
}  

本文為JacenChiu原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處椭员。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末车海,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子隘击,更是在濱河造成了極大的恐慌侍芝,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埋同,死亡現(xiàn)場(chǎng)離奇詭異州叠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)凶赁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)咧栗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人虱肄,你說(shuō)我怎么就攤上這事致板。” “怎么了咏窿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵斟或,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我翰灾,道長(zhǎng)缕粹,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任纸淮,我火速辦了婚禮平斩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咽块。我一直安慰自己绘面,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著揭璃,像睡著了一般晚凿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘦馍,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天歼秽,我揣著相機(jī)與錄音,去河邊找鬼情组。 笑死燥筷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的院崇。 我是一名探鬼主播肆氓,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼底瓣!你這毒婦竟也來(lái)了谢揪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捐凭,失蹤者是張志新(化名)和其女友劉穎拨扶,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柑营,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屈雄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了官套。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酒奶。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奶赔,靈堂內(nèi)的尸體忽然破棺而出惋嚎,到底是詐尸還是另有隱情,我是刑警寧澤站刑,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布另伍,位于F島的核電站,受9級(jí)特大地震影響绞旅,放射性物質(zhì)發(fā)生泄漏摆尝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一因悲、第九天 我趴在偏房一處隱蔽的房頂上張望堕汞。 院中可真熱鬧,春花似錦晃琳、人聲如沸讯检。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)人灼。三九已至围段,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間投放,已是汗流浹背奈泪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跪呈,地道東北人段磨。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓取逾,卻偏偏與公主長(zhǎng)得像耗绿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砾隅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容