15 ポイント 投稿者 GN⁺ 2024-07-28 | 4件のコメント | WhatsAppで共有
  • SQLiteは、小さなBlob(例: サムネイル画像)を個別ファイルで fread()fwrite() を使って読み書きするよりも、35%高速に読み書きできる
  • また、10KBのBlobを保存する単一のSQLiteデータベースは、Blobを個別ファイルとして保存する場合よりも、ディスク容量を約20%少なく使用する
  • この性能差は、SQLiteデータベースで作業する場合は open()close() のシステムコールが1回だけ呼ばれる一方、個別ファイルのBlobを使う場合はBlobごとに open()close() が1回ずつ呼ばれるために生じるとみられる。open()close() のオーバーヘッドは、データベース利用のオーバーヘッドより大きいようだ
  • 容量削減は、個別ファイルがファイルシステムのブロックサイズの次の倍数まで埋められる一方で、BlobはSQLiteデータベース内により高密度に格納されるために生じる

注意事項

  • 35%という数値はおおよその目安。実際の計測値はハードウェア、オペレーティングシステム、実験の詳細によって異なり、実機ではランダムな性能変動もある
  • 35%という数値は、著者が容易に利用できたすべてのシステムでテストを実行した結果。一部のレビューアーは、自分たちのシステムではSQLiteの方が直接I/Oより高いレイテンシを示したと報告している。その差の理由はまだ理解されていない
  • SQLiteは、コールドなファイルシステムキャッシュを使って実験を行う場合、直接I/Oほど良い性能は出ないことが分かっている
  • この文書は、リレーショナルデータベースは直接のファイルシステムI/Oより遅いはずだという一般的な想定に反論している
  • 2022年の研究によれば、実際のワークロードではSQLiteはLinuxのBtrfsおよびExt4と比べておおむね2倍高速だった

測定方法

  • I/O性能は、SQLiteソースツリー内の kvtest.c プログラムを使って測定された
  • このテストプログラムをコンパイルするには、SQLiteのアマルガメーションソースファイル sqlite3.csqlite3.h に加えて、kvtest.c ソースファイルを1つのディレクトリに集め、Unixで次のようなコマンドを実行する
  • このコマンドで生成される kvtest プログラムを使って、100,000個のランダムな非圧縮Blobからなるテストデータベースを作成する。各Blobのサイズは8,000バイトから12,000バイトの間
  • すべてのBlobのコピーをディレクトリ内の個別ファイルとして作るには、--tree コマンドラインオプションを使って export コマンドを実行できる
  • データベースからBlobを読み取る性能と、個別ファイルからBlobを読み取る性能を測定するために、次のコマンドを使う
  • --blob-api オプションを使うと、SQLiteはSQL文を実行する代わりに sqlite3_blob_read() 関数を使ってBlob内容を読み込めるため、読み取りテストではわずかに高速になる

読み取り性能の測定

  • Windows 10では、SQLiteデータベースからのコンテンツ読み取りは、ディスクから直接読み取る場合より約5倍高速
  • Androidでは、SQLiteはディスク読み取りより約35%高速
  • メモリマップされたデータベースで sqlite3_blob_read() を使って読み取る場合、MacとAndroidではディスク上の個別ファイル読み取りより2倍高速で、Windowsでは10倍高速

書き込み性能の測定

  • すべてのシステムで、直接I/OとSQLiteのどちらも書き込み性能は読み取りより5〜15倍遅い
  • 書き込みテストでは、アンチウイルスソフトウェアはSQLiteへの書き込みにはほとんど影響しないが、ディスクへの直接書き込みは約10倍遅くなる
  • これはおそらく、SQLiteは単一のデータベースファイルだけを変更する一方、ディスクへ直接変更する場合はアンチウイルスが検査すべき何千もの個別ファイルを変更するため

一般的な結果

  • SQLiteは、読み取り・書き込みの両方において、別個のディスクファイルに保存されたBlobと十分競争力があり、多くの場合より高速
  • SQLiteは、アンチウイルス保護が有効なWindowsでは、ディスクへの直接書き込みよりはるかに高速
  • 読み取りは、すべてのシステムにおいて、またSQLiteと直接ディスクI/Oのどちらでも、書き込みより約10倍高速
  • I/O性能はオペレーティングシステムとハードウェアによって大きく異なる。結論を出す前に自前で測定する必要がある
  • 一部の他のSQLデータベースエンジンは、開発者にBlobを別ファイルとして保存し、そのファイル名をデータベースに保存するよう勧めている。この場合、Blob全体をデータベースに保存した方が、SQLiteでははるかに高速な読み書き性能を得られる

GN⁺の見解

  • SQLiteの性能が個別ファイルの読み書きを上回るという点は非常に興味深い。これは、データベースを使うアプリケーションの性能向上に役立つ可能性がある
  • ただし、このベンチマーク結果がすべての状況に一般化できるわけではない。データの特性、アクセスパターン、ハードウェア構成などによって変わり得る。重要なアプリケーションでは、実際のワークロードを使ってベンチマークを行うことが重要
  • また、SQLiteにはアンチウイルス検査の影響を受けにくいという利点がある。これは大量の小さなファイルを扱うアプリケーションで特に有用だろう
  • SQLiteの欠点は、すべてのデータが単一ファイルに保存されるため、データベースファイルが破損するとすべてのデータを失う可能性がある点。そのため、データベースファイルを定期的にバックアップすることが重要

4件のコメント

 
iolothebard 2024-07-28

データベースにファイル属性(ファイル名、サイズ、アクセス権限、…)へのアクセスまで含めるのか、
そうでないなら、ファイルI/OではなくブロックI/Oと比較すべきなのでは、という気がします…。
何はともあれ、SQLite が速いのは確かですね。

 
GN⁺ 2024-07-28
Hacker Newsの意見
  • ファイルシステムの属性やメタデータがないため、追加の属性記録や更新が不要で、実ファイルやパイプ/シンボリックリンクの確認、権限チェック、ブロックサイズのアラインメント不一致などもなく、単一の open コマンドだけで済む

    • 機能を削ぎ落とし、汎用設計を無視するなら理解できる話
    • SQLite への fuse マッピングを使い、ディレクトリをマウントしてアクセスすると、性能は同程度か、むしろ遅くなる可能性がある
    • 属性を無効化し、最適化されたブロックサイズでカスタムファイルシステムを作れば、同様の性能を得られる
    • rsync のようなシェルコマンドでファイルを探索・操作できる単純さがある
    • SQLite はパッケージ化された静的アセットやアプライアンス型アプリケーションに適している
  • Windows 10 で 4 倍の高速化が見られるのは、Windows のファイルシステム呼び出しがどれほど遅いかを強調している

  • デジタルピアノから出るすべてのノートをリアルタイムで記録するアイデアがある

    • SQLite を使い、各行がピアノの MIDI イベントである単一テーブルに保存する
    • 性能は良好で、あとから分析できる
  • データベース研究室で、OS 研究と比較するのが興味深かった

    • リレーショナルデータベースは、小さな個別レコードと一貫性のために最適化されている
    • 行サイズが大きくなるにつれて性能が急激に低下する
  • WAL2 モードで sqlite DB に追記することを検討している

    • 書き込み性能のペナルティがほとんどなく、読み取り/分析に大きな利点がある
  • SQLite データベースでは open()close() のシステムコールが 1 回ずつしか呼ばれない

    • 個別ファイルで blob を使う場合よりオーバーヘッドが少ない
  • SQLite の blob フィールドを使ってファイルを保存するのは推奨されない

    • blob の最大サイズは 2GB
    • オブジェクトをバイト列にシリアライズ/デシリアライズしなければならない
    • 他のシステム/サービスとやり取りするにはファイルが必要
    • SQLite には並列リクエストを処理する設定があるが、競合するリクエストによってデータベースがロックされる
  • ファイルシステム上に構築されたものがファイルシステムより速いというのは、最適化されていない方法でファイルシステムを使うと遅いことを意味する

  • SQLite データベースで大量の行を削除するのは、ファイルを削除するより遅い

  • すべてのファイルシステム/ドライブアクセスは OS によって管理される

    • データベースファイルはディスク上にクラスタとして保存される
    • データベース管理システムは、特定のドメインや問題を解決するために便利なよう作られている
 
halfenif 2024-07-28

20年前、ファイルをblobとしてOracle DBに入れるアーキテクチャをうまく使っていたが、その利点を毎回人々に説明しなければならなかった。もちろん、毎回うまくいったわけではなかった。

 
narusas 2024-07-29

20年前なら、オラクルのSAN DISKの価格もかなり高かったでしょうね..