63

元の質問

バックグラウンド

50k 挿入/秒のオーダーの挿入速度を達成するには、SQLiteを微調整する必要があることはよく知られています。ここには、挿入速度の遅さと豊富なアドバイスとベンチマークに関する多くの質問があります。

また、SQLite は大量のデータを処理できるという主張もあり、50 GB 以上のレポートでは適切な設定で問題は発生しません。

ここや他の場所のアドバイスに従ってこれらの速度を達成しましたが、35k-45k の挿入/秒に満足しています。私が抱えている問題は、すべてのベンチマークが 1m 未満のレコードでのみ高速な挿入速度を示していることです。私が見ているのは、挿入速度がテーブルサイズに反比例するように見えるということです。

問題

[x_id, y_id, z_id]私のユース ケースでは、リンク テーブルに数年間 (100 万行/日) にわたって500m から 1b のタプル ( ) を格納する必要があります。値はすべて 1 ~ 2,000,000 の整数 ID です。に単一の索引がありますz_id

最初の 10m 行、最大 35k 挿入/秒のパフォーマンスは優れていますが、テーブルが最大 20m 行になるまでに、パフォーマンスが低下し始めます。現在、約 100 の挿入/秒が表示されています。

テーブルのサイズは特に大きくありません。20m 行の場合、ディスク上のサイズは約 500MB です。

プロジェクトは Perl で書かれています。

質問

これは SQLite の大きなテーブルの現実ですか、それとも 1,000 万行を超えるテーブルで高い挿入率を維持する秘訣はありますか?

可能であれば回避したい既知の回避策

  • インデックスを削除し、レコードを追加して、インデックスを再作成します。これは回避策としては問題ありませんが、更新中に DB を引き続き使用する必要がある場合には機能しません。データベースをx分間/日完全にアクセス不能にすることはできません。
  • テーブルをより小さなサブテーブル/ファイルに分割します。これは短期間で機能し、すでに実験しています。問題は、クエリを実行するときに履歴全体からデータを取得できるようにする必要があることです。これは、最終的に 62 個のテーブル添付ファイルの制限に達することを意味します。アタッチし、一時テーブルに結果を収集し、リクエストごとに何百回もデタッチすると、多くの作業とオーバーヘッドが発生するようですが、他に選択肢がない場合は試してみます。
  • セット SQLITE_FCNTL_CHUNK_SIZE: 私は C (?!) を知らないので、これをやり遂げるためだけに C を学ばない方がいいと思います。ただし、Perl を使用してこのパラメーターを設定する方法がわかりません。

アップデート

大規模なデータセットを処理できるという SQLite の主張にもかかわらず、インデックスが挿入時間をますます遅くしているというティムの提案に従って、次の設定でベンチマーク比較を実行しました。

  • 挿入された行: 1,400 万
  • commit バッチ サイズ: 50,000 レコード
  • cache_sizeプラグマ: 10,000
  • page_sizeプラグマ: 4,096
  • temp_storeプラグマ:メモリ
  • journal_modeプラグマ:削除
  • synchronousプラグマ:オフ

私のプロジェクトでは、以下のベンチマーク結果のように、ファイルベースの一時テーブルが作成され、CSV データをインポートするための SQLite の組み込みサポートが使用されます。次に、一時テーブルが受信側データベースにアタッチされ、 insert-selectステートメントを使用して 50,000 行のセットが挿入されます。したがって、挿入時間は、 ファイルからデータベースへの挿入時間ではなく、テーブルからテーブルへの挿入速度を反映しています。CSV のインポート時間を考慮すると、速度が 25 ~ 50% 低下します (非常に大まかな見積もりで、CSV データのインポートにそれほど時間はかかりません)。

明らかにインデックスがあると、テーブル サイズが大きくなるにつれて挿入速度が遅くなります。

SQLite の挿入速度とテーブル サイズのプロット

上記のデータから、 SQLite では処理できないという主張ではなく、正しい答えをTim の答えに割り当てることができることは明らかです。そのデータセットのインデックス作成がユースケースの一部でない場合、明らかに大規模なデータセットを処理できます。しばらくの間、ロギング システムのバックエンドとして SQLite を使用してきましたが、これはインデックスを作成する必要がありません。

結論

SQLite使用して大量のデータを保存し、インデックスを付けたいと考えている場合は、シャードを使用することが解決策になる可能性があります。最終的に、MD5 ハッシュの最初の 3 文字を使用して一意の列をz作成し、4,096 のデータベースの 1 つへの割り当てを決定することにしました。私のユースケースは本質的にアーカイブであるため、スキーマは変更されず、クエリでシャード ウォーキングが必要になることはありません。非常に古いデータは削減され、最終的には破棄されるため、データベースのサイズには制限があります。したがって、シャーディング、プラグマ設定、および一部の非正規化のこの組み合わせにより、上記のベンチマークに基づいて挿入速度を維持する適切なバランスが得られます。少なくとも 1 万回の挿入/秒。

4

5 に答える 5

9

素晴らしい質問と非常に興味深いフォローアップです!

簡単な発言をしたいと思います。テーブルを小さなサブテーブル/ファイルに分割して後で添付することは、接続されたデータベースの 62 個のハードリミットにすぐに達するため、オプションではないとおっしゃいました。これは完全に真実ですが、データを複数のテーブルにシャーディングし、同じ単一のデータベース (ファイル) を使い続けるという中間のオプションを検討したとは思いません。


私の提案が実際にパフォーマンスに影響を与えることを確認するためだけに、非常に大雑把なベンチマークを行いました。

スキーマ:

CREATE TABLE IF NOT EXISTS "test_$i"
(
    "i" integer NOT NULL,
    "md5" text(32) NOT NULL
);

データ - 200 万行:

  • i= 1..2,000,000
  • md5= の md5 16 進ダイジェストi

各トランザクション = 50,000INSERT秒。


データベース: 1; テーブル: 1; インデックス: 0

0..50000 records inserted in 1.87 seconds
50000..100000 records inserted in 1.92 seconds
100000..150000 records inserted in 1.97 seconds
150000..200000 records inserted in 1.99 seconds
200000..250000 records inserted in 2.19 seconds
250000..300000 records inserted in 1.94 seconds
300000..350000 records inserted in 1.94 seconds
350000..400000 records inserted in 1.94 seconds
400000..450000 records inserted in 1.94 seconds
450000..500000 records inserted in 2.50 seconds
500000..550000 records inserted in 1.94 seconds
550000..600000 records inserted in 1.94 seconds
600000..650000 records inserted in 1.93 seconds
650000..700000 records inserted in 1.94 seconds
700000..750000 records inserted in 1.94 seconds
750000..800000 records inserted in 1.94 seconds
800000..850000 records inserted in 1.93 seconds
850000..900000 records inserted in 1.95 seconds
900000..950000 records inserted in 1.94 seconds
950000..1000000 records inserted in 1.94 seconds
1000000..1050000 records inserted in 1.95 seconds
1050000..1100000 records inserted in 1.95 seconds
1100000..1150000 records inserted in 1.95 seconds
1150000..1200000 records inserted in 1.95 seconds
1200000..1250000 records inserted in 1.96 seconds
1250000..1300000 records inserted in 1.98 seconds
1300000..1350000 records inserted in 1.95 seconds
1350000..1400000 records inserted in 1.95 seconds
1400000..1450000 records inserted in 1.95 seconds
1450000..1500000 records inserted in 1.95 seconds
1500000..1550000 records inserted in 1.95 seconds
1550000..1600000 records inserted in 1.95 seconds
1600000..1650000 records inserted in 1.95 seconds
1650000..1700000 records inserted in 1.96 seconds
1700000..1750000 records inserted in 1.95 seconds
1750000..1800000 records inserted in 1.95 seconds
1800000..1850000 records inserted in 1.94 seconds
1850000..1900000 records inserted in 1.95 seconds
1900000..1950000 records inserted in 1.95 seconds
1950000..2000000 records inserted in 1.95 seconds

データベース ファイル サイズ: 89.2 MiB。


データベース: 1; テーブル: 1; 索引: 1 ( md5)

0..50000 records inserted in 2.90 seconds
50000..100000 records inserted in 11.64 seconds
100000..150000 records inserted in 10.85 seconds
150000..200000 records inserted in 10.62 seconds
200000..250000 records inserted in 11.28 seconds
250000..300000 records inserted in 12.09 seconds
300000..350000 records inserted in 10.60 seconds
350000..400000 records inserted in 12.25 seconds
400000..450000 records inserted in 13.83 seconds
450000..500000 records inserted in 14.48 seconds
500000..550000 records inserted in 11.08 seconds
550000..600000 records inserted in 10.72 seconds
600000..650000 records inserted in 14.99 seconds
650000..700000 records inserted in 10.85 seconds
700000..750000 records inserted in 11.25 seconds
750000..800000 records inserted in 17.68 seconds
800000..850000 records inserted in 14.44 seconds
850000..900000 records inserted in 19.46 seconds
900000..950000 records inserted in 16.41 seconds
950000..1000000 records inserted in 22.41 seconds
1000000..1050000 records inserted in 24.68 seconds
1050000..1100000 records inserted in 28.12 seconds
1100000..1150000 records inserted in 26.85 seconds
1150000..1200000 records inserted in 28.57 seconds
1200000..1250000 records inserted in 29.17 seconds
1250000..1300000 records inserted in 36.99 seconds
1300000..1350000 records inserted in 30.66 seconds
1350000..1400000 records inserted in 32.06 seconds
1400000..1450000 records inserted in 33.14 seconds
1450000..1500000 records inserted in 47.74 seconds
1500000..1550000 records inserted in 34.51 seconds
1550000..1600000 records inserted in 39.16 seconds
1600000..1650000 records inserted in 37.69 seconds
1650000..1700000 records inserted in 37.82 seconds
1700000..1750000 records inserted in 41.43 seconds
1750000..1800000 records inserted in 49.58 seconds
1800000..1850000 records inserted in 44.08 seconds
1850000..1900000 records inserted in 57.17 seconds
1900000..1950000 records inserted in 50.04 seconds
1950000..2000000 records inserted in 42.15 seconds

データベース ファイル サイズ: 181.1 MiB。


データベース: 1; テーブル: 20 (100,000 レコードあたり 1 つ); 索引: 1 ( md5)

0..50000 records inserted in 2.91 seconds
50000..100000 records inserted in 10.30 seconds
100000..150000 records inserted in 10.85 seconds
150000..200000 records inserted in 10.45 seconds
200000..250000 records inserted in 10.11 seconds
250000..300000 records inserted in 11.04 seconds
300000..350000 records inserted in 10.25 seconds
350000..400000 records inserted in 10.36 seconds
400000..450000 records inserted in 11.48 seconds
450000..500000 records inserted in 10.97 seconds
500000..550000 records inserted in 10.86 seconds
550000..600000 records inserted in 10.35 seconds
600000..650000 records inserted in 10.77 seconds
650000..700000 records inserted in 10.62 seconds
700000..750000 records inserted in 10.57 seconds
750000..800000 records inserted in 11.13 seconds
800000..850000 records inserted in 10.44 seconds
850000..900000 records inserted in 10.40 seconds
900000..950000 records inserted in 10.70 seconds
950000..1000000 records inserted in 10.53 seconds
1000000..1050000 records inserted in 10.98 seconds
1050000..1100000 records inserted in 11.56 seconds
1100000..1150000 records inserted in 10.66 seconds
1150000..1200000 records inserted in 10.38 seconds
1200000..1250000 records inserted in 10.24 seconds
1250000..1300000 records inserted in 10.80 seconds
1300000..1350000 records inserted in 10.85 seconds
1350000..1400000 records inserted in 10.46 seconds
1400000..1450000 records inserted in 10.25 seconds
1450000..1500000 records inserted in 10.98 seconds
1500000..1550000 records inserted in 10.15 seconds
1550000..1600000 records inserted in 11.81 seconds
1600000..1650000 records inserted in 10.80 seconds
1650000..1700000 records inserted in 11.06 seconds
1700000..1750000 records inserted in 10.24 seconds
1750000..1800000 records inserted in 10.57 seconds
1800000..1850000 records inserted in 11.54 seconds
1850000..1900000 records inserted in 10.80 seconds
1900000..1950000 records inserted in 11.07 seconds
1950000..2000000 records inserted in 13.27 seconds

データベース ファイルのサイズ: 180.1 MiB。


ご覧のとおり、データを複数のテーブルに分割しても、挿入速度はほぼ一定のままです。

于 2013-06-14T13:47:12.623 に答える