Android 編程下 SQLite 大數據量操作優化


SQLite 因其小巧輕便被安卓系統廣泛采用,當然在操作小數據量時,差異並不明顯;但當 SQLite  在操作略大一點的數據時就顯得力不存心了,這時的 CRUD 操作對移動存儲設備的性能有着極大的要求,另外用戶體驗的良好性也對 SQLite 的性能優化提出了要求。那么,當我們在操作大數據量時如何對 SQLite 進行優化呢?正確的操作是:開啟事務。下面我們通過采用不同的方式向數據庫中插入 10000 條數據來進行比較以體現開啟事務對 SQLite 性能提升方面所做出的貢獻。首先看一張截圖來進行一個感性的認識:

 

從上圖中我們會很清晰的看到通過普通方式插入 10000 條數據和開啟事務插入 10000 條數據之間的差異,整整差了 83 秒。下面我們來看測試代碼:

package cn.sunzn.sqlitedatabase;

import android.app.Activity;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends Activity {

   protected static final int SUCCESS_INSERT_TO_DB_ONE = 1;
   protected static final int SUCCESS_INSERT_TO_DB_TWO = 2;
   private EditText et_usedtime1;
   private EditText et_usedtime2;
   Handler handler = new Handler() {

       public void handleMessage(Message msg) {
           super.handleMessage(msg);
           switch (msg.what) {
           case SUCCESS_INSERT_TO_DB_ONE:
               Integer usetime_one = (Integer) msg.obj;
               et_usedtime1.setText("插入10000條數據耗時:" + usetime_one / 1000 + "秒");
               break;
           case SUCCESS_INSERT_TO_DB_TWO:
               Integer usetime_two = (Integer) msg.obj;
               et_usedtime2.setText("插入10000條數據耗時:" + usetime_two / 1000 + "秒");
               break;
           default:
               break;
           }
       }
   };

   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       et_usedtime1 = (EditText) findViewById(R.id.et_usedtime1);
       et_usedtime2 = (EditText) findViewById(R.id.et_usedtime2);
   }

   /**
    * 1. 普通方式插入數據庫 10000 條數據
    */
   public void insert1(View view) {
       MySQLiteOpenHelper openHelper = new MySQLiteOpenHelper(getApplicationContext());
       final SQLiteDatabase database = openHelper.getWritableDatabase();
       if (database.isOpen()) {
           new Thread() {
               public void run() {
                   long start = System.currentTimeMillis();
                   for (int i = 0; i < 10000; i++) {
                       ContentValues values = new ContentValues();
                       values.put("name", "tom:" + i);
                       database.insert("person", "_id", values);
                   }
                   database.close();
                   long end = System.currentTimeMillis();
                   int usetime_one = (int) (end - start);
                   Message message = new Message();
                   message.what = SUCCESS_INSERT_TO_DB_ONE;
                   message.obj = usetime_one;
                   handler.sendMessage(message);
               };
           }.start();
       }
   }

   /**
    * 2. 開啟事務插入數據庫 10000 條數據
    */
   public void insert2(View view) {
       MySQLiteOpenHelper openHelper = new MySQLiteOpenHelper(getApplicationContext());
       final SQLiteDatabase database = openHelper.getWritableDatabase();
       if (database.isOpen()) {
           new Thread() {
               public void run() {
                   long start = System.currentTimeMillis();
                   database.beginTransaction();
                   for (int i = 0; i < 10000; i++) {
                       ContentValues values = new ContentValues();
                       values.put("name", "tom:" + i);
                       database.insert("person", "_id", values);
                   }
                   database.setTransactionSuccessful();
                   database.endTransaction();
                   database.close();
                   long end = System.currentTimeMillis();
                   int usetime_two = (int) (end - start);
                   Message message = new Message();
                   message.what = SUCCESS_INSERT_TO_DB_TWO;
                   message.obj = usetime_two;
                   handler.sendMessage(message);
               };
           }.start();
       }
   }

   public boolean onCreateOptionsMenu(Menu menu) {
       getMenuInflater().inflate(R.menu.activity_main, menu);
       return true;
   }
}

為什么只是開啟了一個事務就會有這么大的差距呢?很簡單,SQLite 缺省為每個操作開啟了一個事務,那么測試代碼循環插入 10000 次開啟了 10000 個事務,"事務開啟 + SQL 執行 + 事務關閉" 自然耗費了大量的時間,這也是后面顯式開啟事務后為什么如此快的原因。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM