WAL是SQLite3.7.0版本引入的一個重大改進。SQLite官網宣稱在很多使用場景下,WAL模型的效能都要好於預設的DELETE模式。下面將針對幾個主要場景對WAL效能做測試,測試的硬體與xxx保持一致。
純寫場景
1) 測試說明
測試簡單更新事務在WAL模式下與DELETE日誌模式效能對比,測試語句形如:update user set c1=c1+1 where id=xxx,id為主鍵,序列執行更新。通過執行1w個更新事務,統計程式執行時間。
2) 測試結果
測試時間結果以毫秒計算,TPS是每秒執行的事務數,通過事務數與時間相比獲取結果。
|
WAL模式 |
DELETE模式 |
第一輪 |
55176 |
159196 |
第二輪 |
54442 |
164341 |
第三輪 |
56171 |
162329 |
第四輪 |
56167 |
166117 |
第五輪 |
55969 |
163139 |
平均值 |
55581 |
163024 |
TPS |
179.9 |
61.3 |
3) 結果分析
從測試結果來看,WAL日誌模式下,純寫效能要遠遠好於DELETE模式,前者大概是後者的3倍。這個效能差異主要源於每次事務提交,WAL模式只需要將更新的日誌寫入磁碟即可,而DELETE模式修改過程中,首先需要將原始資料頁拷貝到日誌檔案中,並進行fsync;然後再將修改頁寫入磁碟,同時也需要fsync,確保資料落盤,並且還要將日誌檔案清除。因此,寫事務在WAL模式下,只需要一次fsync,並且是順序寫;而DELETE模式下,需要至少兩次fsync(日誌,資料),並且更新的資料可能離散分佈在多個page中,因此可能需要多個fsync來完成。眾所周知,fsync呼叫是非常耗時的,導致DELTE模式下寫效能不如WAL模式。
純讀場景
1) 測試說明
測試WAL模式下,純讀效能資料,測試語句形如:“select * from user where id = xxx”,id為主鍵,對比WAL模式與DELETE模式下讀效能。每個執行緒執行10w次查詢,統計最終執行時間。QPS為每秒執行的查詢數
2) 測試結果
|
WAL模式 |
DELETE模式 |
||
2執行緒 |
4執行緒 |
2執行緒 |
4執行緒 |
|
第一輪 |
2847 |
5050 |
4124 |
8168 |
第二輪 |
2730 |
5795 |
3833 |
8074 |
第三輪 |
2688 |
5675 |
3819 |
8077 |
第四輪 |
2959 |
5894 |
3881 |
7787 |
第五輪 |
2836 |
5924 |
3873 |
7958 |
平均值 |
2817 |
5667 |
3906 |
8012 |
QPS |
7w |
7w |
5.1w |
5w |
3) 結果分析
從結果來看,WAL模式下,讀效能要好於DELETE模式,大概提高了將近30%。這說明開啟WAL模式下,對讀效能也有提高。目前我還沒有找到效能提升的原因,後續仔細閱讀原始碼後,再做分析。
讀寫場景
1) 測試說明
在WAL模式下,事務提交時實際是以append方式寫wal日誌檔案,因此讀寫不衝突;而DELETE模式下,寫事務需要寫DB(快取,檔案),與讀事務讀DB(快取,檔案)衝突,因此只能序列讀寫,通過前面的測試可知,WAL模式下,每秒讀寫事務數比例大概是500:1;DELETE模式下,每秒讀寫事務數比例大概是800:1,這裡的測試不打算比較讀寫同時存在時兩種模式的對比,而是單獨測試WAL,以讀寫比為500:1場景,看看讀寫的QPS和TPS是否與單獨執行有差異。測試中,讀寫執行緒都併發讀寫同一張表,讀採用5個執行緒,主鍵查詢,每個執行緒執行100w個讀;寫採用1個執行緒,主鍵更新,執行1w次寫。測試時間的單位為毫秒,QPS和TPS分別為每秒的讀和寫,QPS=500w/時間,TPS=100w/時間。
2) 測試結果
|
WAL模式 |
|
第一輪 |
67543 |
|
第二輪 |
66812 |
|
第三輪 |
72946 |
|
第四輪 |
78844 |
|
第五輪 |
74501 |
|
平均值 |
72129 |
|
QPS|TPS |
6.94w |
138 |
3) 結果分析
通過讀寫比500:1的測試模型,基本保證了讀寫是同時完成的,從另外一方面來說,就是讀寫是充分競爭的。從測試結果來看,WAL模式下,讀的QPS為6.94w,與單獨測試讀7w的效能幾乎無差異;寫的TPS為138, 較單獨測試寫的179略有下降,這可能與設定的讀寫比有關係。通過測試結果可以充分說明,WAL模式下,讀寫是充分併發的,並且幾乎沒有效能損耗。
批量匯入場景
1) 測試說明
這個測試主要了瞭解WAL模式和DELETE模式下,匯入資料效能對比。建立2個表,每個表匯入10w條記錄,總共20w記錄,觀察匯入的時間。
2) 測試結果
|
WAL模式 |
DELETE模式 |
第一輪 |
28019 |
18036 |
第二輪 |
28500 |
17959 |
第三輪 |
28575 |
17578 |
第四輪 |
29078 |
18076 |
第五輪 |
29184 |
17989 |
平均值 |
28671 |
17909 |
TPS |
6975 |
11167 |
3) 結果分析
從結果來看,DELETE模式的批量匯入效能要好於WAL模式,這主要源於,DELETE模式記錄的是old-page,而insert操作沒有old-page,所以無需記錄日誌,而WAL記錄的是修改頁,所以代價比DELETE模式高。
wal檔案大小測試
1) 測試說明
wal模式下,日誌採用單獨的wal檔案,事務將更新寫入wal檔案,事務執行過程中,不斷寫wal檔案,直到提交後,才有機會做檢查點,控制wal檔案不繼續膨脹。由於端裝置,空間資源也非常稀缺,我們來看看wal 模式和delete模式下日誌檔案對空間的損耗。WAL模式下, wal_autocheckpoint用來控制做檢查點時機,這個引數對WAL檔案影響至關重要,測試也圍繞、這個引數展開。
2) 測試結果
場景 |
日誌檔案容量 |
|
|
WAL模式 |
DELETE模式 |
批量匯入(大事務) |
200M |
4k |
主鍵更新(1w行事務) wal_autocheckpoint=1000 |
20M |
19M |
單條更新(單行事務) 更新1w行 wal_autocheckpoint=1000 |
1M |
4k |
單條更新事務 更新1w行 wal_autocheckpoint=4000 |
4M |
4k |
單條更新事務 更新1w行 wal_autocheckpoint=0 |
42M |
無 |
3) 結果分析
從測試結果來看,批量匯入大事務時,測試中DB檔案200M,產生的WAL日誌檔案也是200M,由於是INSERT操作,DELETE模式下,日誌檔案記錄原始資料頁,所以依然為4k,這4k應該是控制資訊。對於大事務更新操作,WAL模式和DELETE模式產生的日誌量基本相當,只不過一個記錄修改後的資料,一個記錄修改前的資料。對於單行事務,DELETE模式的日誌檔案基本沒有增長,而WAL模式下,日誌檔案與wal_autocheckpoint引數相關,預設情況下該引數值為1000個page,每個page_size為1k,因此大約為1M;調整為4000後,日誌檔案也隨之膨脹到4M;設定為0,亦即關閉檢查點後,更新1w條記錄,將使wal膨脹到42M。因此,無論是WAL模式還是DELETE模式,事務大小都對日誌檔案大小有影響,對於WAL模式,為了控制日誌檔案大小,wal_autocheckpoint引數非常重要。