我的問題直接來自this one,雖然我只對UPDATE感興趣,而且只有這一點。提高SQLite的每秒更新性能?
我已經寫在C/C++
一個應用程序,它使用了大量的SQLite
,大多SELECT/UPDATE
,在一個非常頻繁的間隔(約20個查詢每0.5至1秒)
我的數據庫並不大,約2500個記錄的時刻,這裏是表結構:
CREATE TABLE player (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(64) UNIQUE,
stats VARBINARY,
rules VARBINARY
);
到現在爲止我也沒用過transactions
因爲我提高了代碼,想要刺性能而非表現。
// 10 times execution of this
UPDATE player SET stats = ? WHERE (name = ?)
其中stats
正好150個字符的JSON和name
是從5-10:
然後,我通過僅僅執行10 update
查詢,以下的(在不同的值的循環)測量了我的數據庫的性能字符。
沒有交易,其結果是不能接受的: - 約1充滿第二(0.096每個)
隨着交易中,時間下降x7.5時間: - 約0.11 - 0.16秒(0.013每個)
我嘗試刪除大部分數據庫和/或重新排序/刪除列,看看是否改變了什麼,但沒有。即使數據庫僅包含100個記錄(測試),我也會得到上述數字。
然後我試着用PRAGMA
選擇玩:
PRAGMA synchronous = NORMAL
PRAGMA journal_mode = MEMORY
給我小的時候,但並非總是如此,更像約0.08 - 0.14秒
PRAGMA synchronous = OFF
PRAGMA journal_mode = MEMORY
終於給了我非常小的時候大約0.002 - 0.003秒但我不想使用它,因爲我的應用程序每秒都會保存數據庫,並且數據庫損壞的可能性很高OS /電源故障。
我C SQLite
用於查詢的代碼是:(評論/錯誤處理/不相關的部分省略)
// start transaction
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);
// query
sqlite3_stmt *statement = NULL;
int out = sqlite3_prepare_v2(query.c_str(), -1, &statement, NULL);
// bindings
for(size_t x = 0, sz = bindings.size(); x < sz; x++) {
out = sqlite3_bind_text(statement, x+1, bindings[x].text_value.c_str(), bindings[x].text_value.size(), SQLITE_TRANSIENT);
...
}
// execute
out = sqlite3_step(statement);
if (out != SQLITE_OK) {
// should finalize the query no mind the error
if (statement != NULL) {
sqlite3_finalize(statement);
}
}
// end the transaction
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL);
正如你看到的,這是一個非常典型的TABLE
,記錄數量少,我做一個簡單的簡單UPDATE
正好10次。還有什麼我可以做的,以減少我的UPDATE
次?我正在使用最新的SQLite 3.16.2
。
注:定時以上直接從單個
END TRANSACTION
查詢到來。查詢完成一個簡單的交易,我使用準備好的語句 。
UPDATE:
我進行了一些測試與交易的啓用和禁用和各種更新計數。我進行以下設置測試:
VACUUM;
PRAGMA synchronous = NORMAL; -- def: FULL
PRAGMA journal_mode = WAL; -- def: DELETE
PRAGMA page_size = 4096; -- def: 1024
結果如下:
無交易(10次更新)
- 0.30800秒(0.0308每次更新)
- 0.30200秒
- 0.36200秒
- 0.28600小號ECS
沒有交易記錄(100次更新)
- 2.64400秒(0.02644每個更新)
- 2.61200秒
- 2.76400秒
- 2.68700秒
沒有交易附件(1000次更新)
- 28.02800秒(0.028每個更新)
- 27.73700秒
- ...
與交易(10次更新)
- 0.12800秒(0.0128每個更新)
- 0.08100秒
- 0.16400秒
- 0.10400秒
與交易(100次更新)
- 0.088秒(0.00088每個更新)
- 0.091秒
- 0.052秒
- 0。101秒
與交易(1000次更新)
- 0.08900秒(0.000089每個更新)
- 0.15000秒
- 0.11000秒
- 0.09100秒
我的結論是transactions
time cost per query
沒有意義。也許時代變得越來越龐大,但我對這些數字不感興趣。在單個交易上,10和1000更新之間幾乎沒有時間成本差異。不過,我想知道這是否是我的機器上的硬件限制,並且不能做太多。看來我不能低於~100
毫秒,即使使用WAL,也可以使用單個事務並進行10-1000次更新。
沒有交易,固定的時間成本大約爲0.025
秒。
如果使用languiage C/C++,使用正確的標籤。否則,它看起來像C++,而不是**不同的**語言C!這不是一個代碼評論網站。 – Olaf
@Olaf,唯一'C++'的東西是'std :: string';其餘的是'C'。上面我特別強調了這一點。其次,我不希望有人審查我的代碼,我想要一個更好的方法SQLite來解決我的問題 – user6096479
它不會**編譯爲C,因此它不是C.只是因爲你有相同的語法/語法並不意味着你有相同的語義!誰告訴你C++是「帶類的C」是明顯錯誤的,並且不知道它們中的至少一個是否足夠編寫非平凡的代碼。 – Olaf