私の質問はthisから直接届きますが、私はUPDATEにしか興味がありません。SQLiteのUPDATE-per-secondパフォーマンスを改善しますか?
私は非常に頻繁間隔でSQLite
を多用してC/C++
で書かれたアプリケーション、主にSELECT/UPDATE
、(約20クエリごとに0.5〜1秒)を持つ
私のデータベースは、およそ大きくはありません2500瞬間にレコードが、ここではテーブル構造である:私はコードを向上したためtransactions
を使用して刺しを望んでいたしませんでした。この時点まで
CREATE TABLE player (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(64) UNIQUE,
stats VARBINARY,
rules VARBINARY
);
パフォーマンスよりもむしろ。
そしてIは、(異なる値のループで)以下、単に10 update
クエリを実行することにより、自分のデータベースのパフォーマンスを測定した:
stats
が正確に150文字のJSONと
name
が5~10である
// 10 times execution of this
UPDATE player SET stats = ? WHERE (name = ?)
文字。トランザクションなし
は、結果が許容できない: - :約0.11 - - 0.16秒(0.013それぞれ)約1フル秒(0.096それぞれ)取引に
、時間がx7.5時間をドロップ
データベースの大部分を削除したり、列の順序を変更/削除して変更があったかどうかを確認しようとしましたが、変更しませんでした。データベースに100レコード(テスト済み)が含まれていても上記の数値が得られます。
私はその後、PRAGMA
オプションで遊んでみました:
PRAGMA synchronous = NORMAL
PRAGMA journal_mode = MEMORY
は私に小さな回を与えた常にではないが、より多くのようなおよそ0.08から0.14秒
PRAGMA synchronous = OFF
PRAGMA journal_mode = MEMORY
が最後に私に与えた非常に小さい回約0.002 - 0.003秒私のアプリケーションは毎秒データベースを節約し、データベースの破損の可能性が高いので、使用したくないn 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.28600s ECS
ないトランザクション(100回の更新)
- 2.64400秒(0.02644各更新)
- 2.61200秒
- 2.76400秒
- 2.68700秒
トランザクションなしONS(1,000更新)
- 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秒取引に
(1,000更新)
- 0.08900秒(0.000089各更新)
- 0.15000秒
- 0.11000秒
- 0.09100秒
私の結論はtransactions
time cost per query
には意味がありません。多分、更新回数は膨大になりますが、その数には興味がありません。文字通り、のと1000の更新の間に時間的なコスト差はありません。しかし、私はこれが私のマシン上のハードウェアの制限であり、あまりできないのだろうかと思っています。それは、私はミリ秒以下の単一のトランザクションを使用して行くことができないと10-1000更新の範囲は、WALを使用しても。
トランザクションがない場合、固定時間コストは約0.025
秒です。
あなたはlanguiage C/C++を使用している場合は、正しいタグを使用します。さもなければ、それはC++のように見えますが、**別の**言語ではありません!これはコードレビューサイトではありません。 – Olaf
@Olaf、 'C++ 'の唯一のものは' std :: string'です。残りは 'C 'です。私は特に上記を重視しています。第二に、誰かが私のコードを見直すことを望まない、私は問題を解決するためにSQLiteのより良いアプローチを望む – user6096479
これはC言語ではないので、C言語ではない。あなたは同じセマンティクスを持っているとは限りません! C++が「クラスを持つC」であると言う人は誰もが間違っていて、自明ではないコードを書くのに十分なことは分かっていません。 – Olaf