Sqliteは、サポートされている場合でも非常に大きなデータベースファイルではうまく機能しないことを知っています(sqlite Webサイトで、1GBを超えるファイルサイズが必要な場合は、エンタープライズRDBMSの使用を検討する必要があるというコメントがありました)もはや見つかりません。古いバージョンのsqliteに関連している可能性があります)。
しかし、私の目的のために、他の解決策を検討する前に、それがどれほど悪いのかを知りたいと思います。
私は2ギガバイトから数ギガバイトの範囲のsqliteデータファイルについて話している。誰もこれで経験がありますか?ヒント/アイデアはありますか?
そのため、非常に大きなファイルに対してsqliteでいくつかのテストを行い、いくつかの結論に達しました(少なくとも特定のアプリケーションについて)。
テストには、単一のテーブルまたは複数のテーブルのいずれかを持つ単一のsqliteファイルが含まれます。各テーブルには、約8列、ほぼすべての整数、および4つのインデックスがありました。
アイデアは、sqliteファイルが約50GBになるまで十分なデータを挿入することでした。
単一テーブル
1つのテーブルだけで、複数の行をsqliteファイルに挿入しようとしました。ファイルが約7GBだったとき(行数について詳しくは言えませんが)、挿入に時間がかかりすぎていました。すべてのデータを挿入するテストには24時間程度かかると推定していましたが、48時間後でも完了しませんでした。
これにより、単一の非常に大きなsqliteテーブルには挿入に関する問題があり、おそらく他の操作にも問題があると結論付けられます。
テーブルが大きくなり、すべてのインデックスの挿入と更新に時間がかかるため、これは驚くことではないと思います。
複数のテーブル
次に、データを時間ごとに複数のテーブルに分割してみました(1日に1つのテーブル)。元の1つのテーブルのデータは、約700のテーブルに分割されました。
この設定では挿入に問題はなく、毎日新しいテーブルが作成されるため、時間が経過しても長くはかかりませんでした。
真空の問題
I_like_caffeineが指摘したように、VACUUMコマンドは、sqliteファイルが大きくなると問題になります。より多くの挿入/削除が行われると、ディスク上のファイルの断片化が悪化するため、目標は定期的にVACUUMを実行してファイルを最適化し、ファイル領域を回復することです。
ただし、 documentation で指摘されているように、データベースの完全なコピーが作成されてバキュームが行われ、完了するまでに非常に長い時間がかかります。そのため、データベースが小さいほど、この操作は速く終了します。
結論
私の特定のアプリケーションでは、バキュームパフォーマンスと挿入/削除速度の両方を最大限に活用するために、おそらく1日に1つのデータを複数のdbファイルに分割します。
これはクエリを複雑にしますが、私にとっては、これだけのデータにインデックスを付けることができるのは価値のあるトレードオフです。追加の利点は、dbファイル全体を削除するだけで1日分のデータを削除できることです(アプリケーションの一般的な操作)。
速度が問題になる時期を確認するには、ファイルごとのテーブルサイズも監視する必要があります。
自動バキューム 以外のインクリメンタルバキュームメソッドがないように見えるのは残念です。バキュームの目的はファイルを最適化することなので(ファイルスペースは大したことではありません)、自動バキュームは行いません。実際、文書化は断片化を悪化させる可能性があると述べているため、定期的にファイルを完全に削除する必要があります。
プラットフォームで50 GB以上のDBSを使用しています。申し分なく機能しません。すべてを正しく行っていることを確認してください!事前定義されたステートメントを使用していますか? * SQLITE 3.7.3
これらの設定を適用します(DBを作成した直後)
PRAGMA main.page_size = 4096;
PRAGMA main.cache_size=10000;
PRAGMA main.locking_mode=EXCLUSIVE;
PRAGMA main.synchronous=NORMAL;
PRAGMA main.journal_mode=WAL;
PRAGMA main.cache_size=5000;
これが他の人を助け、ここでうまくいくことを願っています
顕著なパフォーマンスの問題なしに、最大3.5GBのサイズのSQLiteデータベースを作成しました。正しく覚えていれば、SQLite2にはいくつかの下限があったと思いますが、SQLite3にそのような問題があるとは思いません。
SQLite Limits ページによると、各データベースページの最大サイズは32Kです。また、データベースの最大ページは1024 ^ 3です。したがって、私の計算では、最大サイズとして32テラバイトになります。 SQLiteの制限を超える前に、ファイルシステムの制限に達すると思います。
挿入に48時間以上かかった理由の多くは、インデックスが原因です。信じられないほど高速です:
1-すべてのインデックスを削除2-すべての挿入を実行3-インデックスを再度作成
通常の推奨に加えて:
SQLite3の経験から次のことを学びました。
質問/コメントを歓迎します。 ;-)
7GBのSQLiteデータベースがあります。内部結合で特定のクエリを実行するには2.6秒かかります。これを高速化するために、インデックスを追加してみました。追加したインデックスに応じて、クエリが0.1秒に下がったり、最大で7秒になったりすることがありました。私の場合の問題は、列が非常に重複している場合、インデックスを追加するとパフォーマンスが低下することだと思います:(
Sqliteスケーリングに関する主な不満は次のとおりです。
Vacuumコマンドを使用すると、大きなsqliteファイルで問題が発生しました。
Auto_vacuum機能はまだ試していません。頻繁にデータを更新および削除することが予想される場合、これは一見の価値があります。