4

データベースに行を書き込むためのテストをセットアップしました。各トランザクションは 10,000 行を挿入し、更新はありません。各ステップは、最後のステップよりも長い線形時間がかかります。最初の 10 ステップは、コミットを実行するのに次の時間 (ミリ秒) を要しました

568、772、942、1247、1717、1906、2268、2797、2922、3816、3945

500,000 行のテーブルに 10,00 行を追加するまでに、コミットに 37149 ミリ秒かかります!

  • 外部キー制約はありません。

  • 私はWALを使用してパフォーマンスを向上させていることを発見しました(上記の数値を示します)が、それでも線形劣化

  • PRAGMA Synchronous=OFF は効果なし

  • PRAGMA locked_mode=EXCLUSIVE は効果がありません

  • 追加のインデックスと追加のインデックスなしで実行しました。ほぼ一定の時間差を作ったので、依然として直線的な劣化でした。

私が持っている他のいくつかの設定

  • setAutocommit(false)
  • プラグマ page_size = 4096
  • PRAGMA ジャーナルサイズ制限 = 104857600
  • PRAGMA count_changes = オフ
  • PRAGMA cache_size = 10000
  • スキーマには Id INTEGER PRIMARY KEY ASC があり、その挿入はインクリメンタルで、Sqlite によって生成されます

次のように完全なスキーマ(インデックスの有無にかかわらず実行しましたが、含めました)

create table if not exists [EventLog] (
Id INTEGER PRIMARY KEY ASC, 
DocumentId TEXT NOT NULL, 
Event TEXT NOT NULL, 
Content TEXT NOT NULL, 
TransactionId TEXT NOT NULL, 
Date INTEGER NOT NULL, 
User TEXT NOT NULL)

create index if not exists DocumentId ON EventLog (DocumentId)

create index if not exists TransactionId ON EventLog (TransactionId)

create index if not exists Date ON EventLog (Date)

これは、Windows 環境で実行されている sqlite-jdbc-3.7.2 を使用しています。

4

2 に答える 2

3

SQLite のテーブルとインデックスは、内部的に B-Tree として編成されます。テーブルでは、ROWID がソート キーです。(あなたINTEGER PRIMARY KEYはロウイドです。)


挿入された ID が、テーブルに既に存在する最大の ID よりも大きくない場合、レコードは追加されず、ツリーの途中に挿入されます。1 回のトランザクションで十分な数のレコードを挿入するときに、ID の分布がランダムである場合、データベースのほぼすべてのページを書き換える必要があります。

これを避けるには、

  1. ID を昇順に挿入します。また
  2. NULLSQLite が次の値を選択するように ID を挿入します。また
  3. SQLite が ID フィールドを Rowid として宣言することでINTEGER UNIQUE(またはINTEGER追加のチェック/インデックスが必要ない場合にのみ)、ID フィールドを使用するのを防ぎ、テーブルの順序を ID から独立させます。

インデックスの場合、ランダムな分布でインデックス付きフィールドを挿入するには、インデックスをランダムな位置で更新する必要があります。テーブルと同様に、1 回のトランザクションで十分な数のレコードを挿入すると、インデックスのほぼすべてのページを書き換える必要があります。

大量のデータをロードする場合は、インデックスを使用せずにこれを行い、後で再作成することをお勧めします。(他のデータベースとは異なり、SQLite にはインデックスを一時的に無効にする機能はありません。削除するだけです。)

于 2012-10-01T18:25:58.870 に答える
0

参考までに、キーの内容に関して構造を限定していませんが、99.999% の場合、それは GUID になります。したがって、パフォーマンスの問題を解決するために、最初の 8 桁の 16 進数に時間ベースの値を使用して順次 GUID を生成するアルゴリズムを作成しました。GUID のブロックが初期の時間値を使用して生成された場合でも、これは非常にうまく機能しました。

于 2012-10-16T14:37:51.333 に答える