SQLite資料插入效率低 速度慢的方法比較

2021-09-29 07:50:01 字數 3261 閱讀 8585

執行準備這種插入方式是最快的,比拼接sql語句直接插入(insert)要快。

sqlite資料庫由於其簡單、靈活、輕量、開源,已經被越來越多的被應用到中小型應用中。甚至有人說,sqlite完全可以用來取代c語言中的檔案讀寫操作。並且提高大資料的處理能力(sqlite最高支援2pb大小的資料)。直接使用sql語句的插入效率簡直低的令人髮指的。後來不斷查文件、查資料,才發現了一條快速的「資料插入」之路。本文就以插入資料為例,整合網上和資料書中的各種提高sqlite效率的方法,給出提高sqlite資料插入效率的完整方法。

使用vccode編譯,sqlite版本為3.7.15.2 ,電腦cpu為二代i3處理器,記憶體6g。實驗之前,先建立要插入資料的表:

create table test (id integer , x int

, y double

)

sqlite的api中直接執行sql的函式是:

int

sqlite3_exec

(sqlite3*

,const

char

*sql,

int(

*callback)

(void*,

int,

char**

,char**

),void*,

char

**errmsg)

;

直接使用insert語句的字串進行插入,程式部分**,如下:

for

(int i=

0;i++i)

這個程式執行的太慢了,我已經沒時間等待了,估算了一下,基本上是 7.826 條/s

然寫同步設為off後,速度又有小幅提公升,但是仍然較慢。又一次踏上了尋找提高sqlite插入效率方法的道路上。終於,發現,sqlite執行sql語句的時候,有兩種方式:一種是使用前文提到的函式sqlite3_exec(),該函式直接呼叫包含sql語句的字串;另一種方法就是「執行準備」(類似於儲存過程)操作,即先將sql語句編譯好,然後再一步一步(或一行一行)地執行。如果採用前者的話,就算開起了事務,sqlite仍然要對迴圈中每一句sql語句進行「詞法分析」和「語法分析」,這對於同時插入大量資料的操作來說,簡直就是浪費時間。因此,要進一步提高插入效率的話,就應該使用後者。

「執行準備」主要分為三大步驟:

呼叫函式

int

sqlite3_prepare_v2

( sqlite3 *db,

const

char

*zsql,

int nbyte, sqlite3_stmt *

*ppstmt,

const

char

**pztail)

;

並且宣告乙個指向sqlite3_stmt物件的指標,該函式對引數化的sql語句zsql進行編譯,將編譯後的狀態存入ppstmt中。

2. 呼叫函式 sqlite3_step() ,這個函式就是執行一步(本例中就是插入一行),如果函式返回的是sqlite_row則說明仍在繼續執行,否則則說明已經執行完所有操作;

3. 呼叫函式 sqlite3_finalize(),關閉語句。

關於執行準備的api的具體語法,詳見官方文件。本文中執行準備的c++**如下:

sqlite3_exec

(db,

"begin;",0

,0,0

);

sqlite3_stmt *stmt;

const

char

* sql =

"insert into t1 values(?,?,?,?)"

;sqlite3_prepare_v2

(db,sql,

strlen

(sql)

,&stmt,0)

;for

(int i=

0;i++i)

sqlite3_finalize

(stmt)

;sqlite3_exec

(db,

"commit;",0

,0,0

);

此時測試資料插入效率為:265816條/s,也就是說,插入100000000條資料,需要376秒 = 6.27分。這個速度已經很滿意了。

所謂」事務「就是指一組sql命令,這些命令要麼一起執行,要麼都不被執行。在sqlite中,每呼叫一次sqlite3_exec()函式,就會隱式地開啟了乙個事務,如果插入一條資料,就呼叫該函式一次,事務就會被反覆地開啟、關閉,會增大io量。如果在插入資料前顯式開啟事務,插入後再一起提交,則會大大提高io效率,進而加資料快插入速度。

開啟事務只需在上述**的前後各加一句開啟與提交事務的命令即可:

sqlite3_exec

(db,

"begin;",0

,0,0

);for(

int i=

0;i++i)

sqlite3_exec

(db,

"commit;",0

,0,0

);

顯式開啟事務後,這個程式執行起來明顯快很多,估算效率達到了34095條/s,較原始方法提公升約5000倍。

在sqlite中,資料庫配置的引數都由編譯指示(pragma)來實現的,而其中synchronous選項有三種可選狀態,分別是full、normal、off。這篇部落格以及官方文件裡面有詳細講到這三種引數的設定。簡要說來,full寫入速度最慢,但保證資料是安全的,不受斷電、系統崩潰等影響,而off可以加速資料庫的一些操作,但如果系統崩潰或斷電,則資料庫可能會損毀。

sqlite3中,該選項的預設值就是full,如果我們再插入資料前將其改為off,則會提高效率。如果僅僅將sqlite當做一種臨時資料庫的話,完全沒必要設定為full。在**中,設定方法就是在開啟資料庫之後,直接插入以下語句:

sqlite3_exec

(db,

"pragma synchronous = off; ",0

,0,0

);

此時,經過測試,插入速度已經變成了41851條/s,也就是說,插入100000000條資料,需要2389秒 = 39.8分。

綜上所述啊,sqlite插入資料效率最快的方式就是:事務+關閉寫同步+執行準備(儲存過程),如果對資料庫安全性有要求的話,就開啟寫同步。

提公升SQLite資料插入效率低 速度慢的方法

本文為本人原創,請尊重個人勞動成果 sqlite資料庫由於其簡單 靈活 輕量 開源,已經被越來越多的被應用到中小型應用中。甚至有人說,sqlite完全可以用來取代c語言中的檔案讀寫操作。因此我最近編寫有關遙感資料處理的程式的時候,也將sqlite引入進來,以提高資料的結構化程度,並且提高大資料的處理...

提公升SQLite資料插入效率低 速度慢的方法

sqlite資料庫由於其簡單 靈活 輕量 開源,已經被越來越多的被應用到中小型應用中。甚至有人說,sqlite完全可以用來取代c語言中的檔案讀寫操作。因此我最近編寫有關遙感資料處理的程式的時候,也將sqlite引入進來,以提高資料的結構化程度,並且提高大資料的處理能力 sqlite最高支援2pb大小...

sqlite插入資料效率提公升解決方案

sqlite插入效率對比 建表 create table if not existstttable id integer primary key autoincrement,name varchar 100 筆者電腦配置 硬碟是250g三星ssd硬碟 cpu os 記憶體如下 理論 sqlite 插...