• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      android中SQLite數據庫中用insert同時插入多條記錄的方法和效率比較

       my360account 2014-11-19

      轉載: android中SQLite數據庫中用insert同時插入多條記錄的方法和效率比較

      在Android開發中我們常會遇到這樣一種情況:在建立一個SQLite數據庫時,想同時插入大量數據。那么應該怎么做呢?

      下面筆者以插入20條記錄為例:

      1.   將同時插入大量的數據寫成一條SQL語句
      2.  最笨的方法用insert語句一條一條的輸入
      3. 使用事務

      代碼如下:

      public class DateBaseOpenHelper extends SQLiteOpenHelper {

           public static final String DBNAME="radiomap";
           public static final int VERSION=1;
           public DateBaseOpenHelper(Context context){
            super(context,DBNAME,null,VERSION);
           }
       @Override
       public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
             db.execSQL("create table radiomap(location varchar(20),ap1 int,ap2 int)");
             long a=System.currentTimeMillis();
             db.execSQL("insert into radiomap(location,ap1,ap2) select 'x=1,y=1',-80,-73 " +
               "union all select 'x=2,y=3',80,40 union all select 'x=3,y=5',30,20 "+
               "union all select 'x=4,y=5',3,2 union all select 'x=30,y=50',30,20 union all select 'x=3,y=5',40,20"
               +" union all select 'x=3,y=5',6,20 union all select 'x=3,y=5',6,7 union all select 'x=3,y=5',7,8 union all select 'x=3,y=5',8,9 union all select 'x=3,y=5',9,9" +
                 " union all select 'x=3,y=5',3,5 union all select 'x=3,y=5',7,20 union all select 'x=3,y=5',4,20 union all select 'x=3,y=5',5,20 union all select 'x=3,y=5',6,20" +
                 " union all select 'x=3,y=5',3,6 union all select 'x=3,y=5',7,7 union all select 'x=3,y=5',3,8 union all select 'x=3,y=5',8,2");
             long b=System.currentTimeMillis();
             long c=b-a;
             Log.i("LocationActivity", String.valueOf(c));
             
             a=System.currentTimeMillis();
             db.beginTransaction();
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',2,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',4,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',6,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',2,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',4,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',6,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',1,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',1,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',1,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',2,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',2,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',2,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',3,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',3,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',3,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',4,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=7',5,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',4,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',5,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',5,5)");
             db.setTransactionSuccessful();
             db.endTransaction();
             b=System.currentTimeMillis();
             Log.i("LocationActivity", String.valueOf(b-a));
              
             a=System.currentTimeMillis();
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=7,y=8',7,8)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=8,y=9',8,9)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=9,y=10',9,10)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',2,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',4,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',6,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',2,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',2,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',2,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',3,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',3,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',3,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',4,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',4,4)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',4,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',5,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=7',6,5)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=6,y=7',5,7)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=4,y=5',6,3)");
             db.execSQL("insert into radiomap(location,ap1,ap2) values('x=5,y=6',6,5)");
             b=System.currentTimeMillis();
             Log.i("LocationActivity", String.valueOf(b-a));
       }

       

      第一種方式及:

      insert into 表名(列名1,列名2)    
       select  值1,值2
       union all  
       select 值1,值2  
       union all  
       select 值1,值2 

      以上三種方式測試結果,及運行效率:

      第一種方式為9ms

      用事務的為:86ms

      第三種直接用insert插入的為:29ms

      這是因為本次測試用了20條數據,所以用事務的反而比不用的開銷大時間長。若1000條以上則明顯快于直接用insert插入的。

       

       

      今天有個朋友測試 SQLite,然后得出的結論是:SQLite 效率太低,批量插入1000條記錄,居然耗時2分鐘!
      下面是他發給我的測試代碼。我暈~~~~~~
      usingSystem.Data;
      usingSystem.Data.Common;
      usingSystem.Data.SQLite;
      //創建數據庫文件
      File.Delete("test1.db3");
      SQLiteConnection.CreateFile("test1.db3");
      DbProviderFactory factory=SQLiteFactory.Instance;
      using(DbConnection conn=factory.CreateConnection())
      {
      //連接數據庫
      conn.ConnectionString="Data Source=test1.db3";
      conn.Open();
      //創建數據表
      stringsql="create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";
      DbCommand cmd=conn.CreateCommand();
      cmd.Connection=conn;
      cmd.CommandText=sql;
      cmd.ExecuteNonQuery();
      //添加參數
      cmd.Parameters.Add(cmd.CreateParameter());
      //開始計時
      Stopwatch watch=newStopwatch();
      watch.Start();
      //連續插入1000條記錄
      for(inti=0; i<1000; i++)
      {
      cmd.CommandText="insert into [test1] ([s]) values (?)";
      cmd.Parameters[0].Value=i.ToString();
      cmd.ExecuteNonQuery();
      }
      //停止計時
      watch.Stop();
      Console.WriteLine(watch.Elapsed);
      }
      哎~~~~一個常識性的錯誤,我加幾行代碼 (新增代碼標記"http:// <-------------------")。
      usingSystem.Data;
      usingSystem.Data.Common;
      usingSystem.Data.SQLite;
      //創建數據庫文件
      File.Delete("test1.db3");
      SQLiteConnection.CreateFile("test1.db3");
      DbProviderFactory factory=SQLiteFactory.Instance;
      using(DbConnection conn=factory.CreateConnection())
      {
      //連接數據庫
      conn.ConnectionString="Data Source=test1.db3";
      conn.Open();
      //創建數據表
      stringsql="create table [test1] ([id] INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";
      DbCommand cmd=conn.CreateCommand();
      cmd.Connection=conn;
      cmd.CommandText=sql;
      cmd.ExecuteNonQuery();
      //添加參數
      cmd.Parameters.Add(cmd.CreateParameter());
      //開始計時
      Stopwatch watch=newStopwatch();
      watch.Start();
      DbTransaction trans=conn.BeginTransaction();//<-------------------
      try
      {
      //連續插入1000條記錄
      for(inti=0; i<1000; i++)
      {
      cmd.CommandText="insert into [test1] ([s]) values (?)";
      cmd.Parameters[0].Value=i.ToString();
      cmd.ExecuteNonQuery();
      }
      trans.Commit();//<-------------------
      }
      catch
      {
      trans.Rollback();//<-------------------
      throw;//<-------------------
      }
      //停止計時
      watch.Stop();
      Console.WriteLine(watch.Elapsed);
      }
      執行一下,耗時0.2秒。這差距是不是太大了點?
      為什么只是簡單啟用了一個事務會有這么大的差距呢?很簡單,SQLite 缺省為每個操作啟動一個事務,那么原代碼1000次插入起碼開啟了1000個事務,"事務開啟 + SQL 執行 + 事務關閉"自然耗費了大量的時間,這也是后面顯示啟動事務后為什么如此快的原因。其實這是數據庫操作的基本常識,大家要緊記,不好的代碼效率差的不是一點半點。

       

       

      最近在做android項目的時候遇到一個問題,應用程序初始化時需要批量的向sqlite中插入大量數,導致應用啟動過慢。
      android使用的是sqlite數據庫,sqlite是比較輕量級的數據庫,在Google了之后發現,sqlite事務處理的問題,在sqlite插入數據的時候默認一條語句就是一個事務,有多少條數據就有多少次磁盤操作。我的應用初始5000條記錄也就是要5000次讀寫磁盤操作。

      解決方法:

      添加事務處理,把5000條插入作為一個事務

      dataBase.beginTransaction();       //手動設置開始事務

      //數據插入操作循環

      dataBase.setTransactionSuccessful();       //設置事務處理成功,不設置會自動回滾不提交

      dataBase.endTransaction();       //處理完成

       


      SQLite的數據庫本質上來講就是一個磁盤上的文件,所以一切的數據庫操作其實都會轉化為對文件的操作,而頻繁的文件操作將會是一個很好時的過程,會極大地影響數據庫存取的速度。
      例如:向數據庫中插入100萬條數據,在默認的情況下如果僅僅是執行
      sqlite3_exec(db, “insert into name values ‘lxkxf', ‘24'; ”,0,0,&zErrMsg);
      將會重復的打開關閉數據庫文件100萬次,所以速度當然會很慢。因此對于這種情況我們應該使用“事務”。
      具體方法如下:在執行SQL語句之前和SQL語句執行完畢之后加上
      rc=sqlite3_exec(db,"BEGIN;",0,0,&zErrMsg);
      //執行SQL語句
      rc=sqlite3_exec(db,"COMMIT;",0,0,&zErrMsg);
      這樣SQLite將把全部要執行的SQL語句先緩存在內存當中,然后等到COMMIT的時候一次性的寫入數據庫,這樣數據庫文件只被打開關閉了一次,效率自然大大的提高。有一組數據對比:
      測試1:1000INSERTs
      CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));
      INSERT INTO t1 VALUES(1,13153,'thirteen thousand one hundred fifty three');
      INSERT INTO t1 VALUES(2,75560,'seventy five thousand five hundred sixty');
      ...995lines omitted
      INSERT INTO t1 VALUES(998,66289,'sixty six thousand two hundred eighty nine');
      INSERT INTO t1 VALUES(999,24322,'twenty four thousand three hundred twenty two');
      INSERT INTO t1 VALUES(1000,94142,'ninety four thousand one hundred forty two');
      SQLite2.7.6:
      13.061
      SQLite2.7.6(nosync):
      0.223

      測試2: 使用事務25000INSERTs
      BEGIN;
      CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
      INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
      ...24997lines omitted
      INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
      INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
      COMMIT;
      SQLite2.7.6:
      0.914
      SQLite2.7.6(nosync):
      0.757

      可見使用了事務之后卻是極大的提高了數據庫的效率。但是我們也要注意,使用事務也是有一定的開銷的,所以對于數據量很小的操作可以不必使用,以免造成而外的消耗。


        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發表

        請遵守用戶 評論公約

        類似文章 更多

        主站蜘蛛池模板: 国产精品VA尤物在线观看| 18级成人毛片免费观看| 无码人妻一区二区三区兔费| 久久99热只有频精品6狠狠| 欧美国产日韩A在线观看| 欧美福利电影A在线播放| 久久无码人妻丰满熟妇区毛片 | 私人毛片免费高清影视院| 久久婷婷五月综合97色直播| 成人片黄网站色大片免费观看| 亚洲日韩一区精品射精| 国产啪视频免费观看视频| 国产欧美日韩一区二区三区| 国产AV影片麻豆精品传媒| 天天摸天天做天天爽2020| 一本大道久久东京热AV | 国产欧美在线一区二区三| 久久久综合香蕉尹人综合网 | jizz视频在线观看| 亚洲国产日韩A在线亚洲| 午夜免费福利小电影| 久久精品国产亚洲不AV麻豆| 国产成人一区二区不卡| 欧美亚洲日韩国产人成在线播放| 麻豆国产AV剧情偷闻女邻居内裤| 久久99精品国产99久久6尤物| 国产欧美日韩亚洲一区二区三区| 国产精品情侣呻吟对白视频| 成年女人喷潮免费视频| 亚洲蜜臀av乱码久久| 亚洲精品V天堂中文字幕| 狠狠色丁香婷婷综合尤物| A毛片终身免费观看网站| 成人H视频在线观看| 日本一道本高清一区二区| 国厂精品114福利电影免费| 亚洲国产成人无码网站| 久久婷婷大香萑太香蕉AV人| 亚洲欧美日韩愉拍自拍美利坚| 精品人妻少妇嫩草AV无码专区 | 少妇富婆高级按摩出水高潮|