私は...するだろう:
- ステートメントを準備します(まだ行っていない場合)
- トランザクションあたりの INSERT の量を減らします (10 秒 = 500,000 が適切に聞こえます)
PRAGMA locking_mode = EXCLUSIVE;
できれば使う
また、(あなたが知っているかどうかはわかりませんが)PRAGMA cache_size
MBではなくページです。PRAGMA cache_size * PRAGMA page_size
asまたは SQLite >= 3.7.10 でターゲット メモリを定義してくださいPRAGMA cache_size = -kibibytes;
。100 万に設定すると、1 GB または 2 GB になります。
しかし、INSERTでどのようcache_size
に役立つのか興味があります...
違いが生じる場合は、ベンチマークを試すこともできますPRAGMA temp_store = FILE;
。
そしてもちろん、データベースが書き込まれていないときはいつでも:
PRAGMA shrink_memory;
VACUUM;
データベースで何をしているかに応じて、これらも役立つ場合があります。
PRAGMA auto_vacuum = 1|2;
PRAGMA secure_delete = ON;
次のプラグマを使用していくつかのテストを実行しました。
busy_timeout=0;
cache_size=8192;
encoding="UTF-8";
foreign_keys=ON;
journal_mode=WAL;
legacy_file_format=OFF;
synchronous=NORMAL;
temp_store=MEMORY;
テスト #1:
INSERT OR IGNORE INTO test (time) VALUES (?);
UPDATE test SET count = count + 1 WHERE time = ?;
1 秒あたり最大 109,000 の更新。
テスト #2:
REPLACE INTO test (time, count) VALUES
(?, coalesce((SELECT count FROM test WHERE time = ? LIMIT 1) + 1, 1));
毎秒最大 120,000 の更新でピークに達しました。
私も試しPRAGMA temp_store = FILE;
てみましたが、更新は毎秒約1〜2k低下しました。
1 回のトランザクションで 7M の更新が行われる場合、journal_mode=WAL
は他のすべてよりも遅くなります。
データベースに 35,839,987 レコードを入力したところ、65521 回の更新のバッチごとにセットアップに 4 秒近くかかっていますが、16 MB のメモリ消費にも達していません。
わかりました、ここに別のものがあります:
INTEGER PRIMARY KEY 列のインデックス (実行しないでください)
INTEGER PRIMARY KEY で列を作成すると、SQLite はこの列をテーブル構造のキー (インデックス) として使用します。これは、この列の非表示のインデックスです (SQLite_Master テーブルには表示されないため)。列に別のインデックスを追加する必要はなく、使用されることはありません。さらに、INSERT、DELETE、および UPDATE 操作が遅くなります。
PK を NOT NULL + UNIQUE として定義しているようです。PK は暗黙的に UNIQUE です。