web-dev-qa-db-ja.com

「データベースに大きなblobを格納するとパフォーマンスが低下する」とはどういう意味ですか?

データベースの内部を知っている人にとって、これは簡単な質問かもしれませんが、データベースに大きなBLOB(たとえば、400 MBの映画)を格納するとパフォーマンスが低下することになり、それが正確に何を意味するのかを明確に説明できますか?これはインターネット全体でよく見られる申し立てですが、実際に説明されたことはありません。

具体的には、SharePoint/MSSQLのパフォーマンス、つまりファイルアップロードのパフォーマンス、サイトの参照、リストの表示、ドキュメントのオープンなどについて言及しています。データベースが大きくなりすぎると、動作が遅くなると言われています。ファイルシステムへのBlobの外部化(SharePointではリモートBlobストレージと呼ばれ、データベースからファイルを移動し、参照のみを残します)はこれをある程度解決するはずですが、正確には-最下位レベルで-違いは何ですか?巨大なファイルがデータベースに保存されている場合、バックアップに時間がかかることは明らかです...しかし、どの操作が正確に影響を受け、その基本的なメカニズムは何ですか(つまり、データベースの外部のファイルシステムに保存されているファイルは、どのように異なる方法でアクセスまたは保存されますか?)

ID(guid, PK), FileName(string), Data(varbinary(max))を含む単純なテーブルがあるとします。Data列が大きいと、ウェブサイトにファイルのリストを表示するなどの操作が本当に遅くなります(内部的にはSELECT FileName FROM table)、または新しい行を挿入しますか?実際のバイナリコンテンツの列にインデックスが付けられるのとは異なります。

このような質問が既にあったことは知っていますが、十分な説明が見つかりませんでした。

8
w128

これは実際にはDBシステムに依存しますが、BLOBで考慮しなければならない1つの主要なことはトランザクション処理です。ファイルシステムへの外部化により、トランザクションからバイナリデータへの変更を行います。これにより、DBが完全なロールバックメカニズムなどのACIDコンプライアンスを保証する状況とは対照的に、通常はwrite操作が高速になります。

BLOBテーブルからデータベースからデータを取得する場合、仮想的に低速の読み取り操作も発生する可能性がありますなし実際にBLOBデータを選択します。これは、DBが残りの行をよりローカライズしてディスクに格納するため、より高速になるためです。読み取りアクセス(ただし、最近のほとんどのDBシステムは、実際のバイナリデータを別のディスク領域またはテーブルスペースに格納するのに十分に賢いので、これを実際のシナリオでテストしないと、ここで一般的な仮定を行うべきではありません)。

9
Doc Brown

これは通常、帯域幅の問題です。 1時間に数百本のビデオを配信している場合、データベースの内外で帯域幅を占有し、主にバッファをコピーしています。また、単純にテーブルからすべての列を選択する単純なクエリ(ORMツールによって自動生成される可能性がある)がある場合にも問題になります。また、ファイルシステムのようにファイルの断片化の影響を受けますが(この場合はレコードの断片化を除きます)、(通常は)断片化を解消するツールがありません。 BLOBも変更している場合(たとえば、何らかのビデオ編集をサポートしている場合)、データベースはBLOB全体をロールバックまたはREDOセグメントにコピーし、更新されたBLOBをデータベースに書き込みます。これで、数百メガバイトをコピーして、トランザクションが終了するまでREDOセグメントを拘束しています(REDOセグメントのサイズが固定されている場合に発生する可能性のある問題は言うまでもありません)。

7
TMN

SQL Server FileTables を調べてください。このアイデアは、ファイルシステムレベルのアクセスとパフォーマンス、データベースへのアクセス、統合されたセキュリティとサービスを提供することです。データベースには、場合によってはオーバーヘッドのパフォーマンスがあります。 Webサーバー上のハードコードされたHTMLファイルを、データベースからコンテンツをフェッチする必要があるファイルと比較するだけです。

データベースにblobを格納することが見つからなかったアプリケーションがパフォーマンスに大きな制限を課したと想像してください。 FileTableを使用したコーディングの変更はほとんどありません。また、多くのコーディングを行わなくても、データベースレベルとファイルレベルでトランザクションを管理できます。ファイルとメタデータはSQLで利用できます。

Windows Serverでは、データベーストランザクションオーバーヘッドを使用せずにファイルにアクセスするための共有ドライブが作成されます。

これは、MicrosoftがSQL Server 2012で「そのまま」処理しようとした一般的な問題です。アップグレードを正当化するための悪い機能ではありません。

6
JeffO

これが醜い理由を知るには、データベースがハードドライブ(具体的には行)にどのように保存されるかを知る必要があります。ディスクに保存された行の物理的な内容は、静的なものと動的なものに分けられます。固定長のint、byte、char(n)などのフィールドが最初にリストされます。続くのは、続く可変長フィールドの数を指す固定長の数です。すべての可変フィールド(プログラマーに提示される列の順序に関係なく)が最後に追加され、可変長フィールドが占めるスペースの量を決定する固定長の数がそれぞれに追加されます。

具体的な例を挙げましょう。私のテーブルが次のとおりだとします:

_char(3) A
varchar(4) B
int C
_

次に、INSERT INTO mytable (A, B, C) VALUES ('AAA', 'B', 256)を実行するとします。データベースでは、その行はおそらく次のように格納されます。 Representation of row saved in database

フィールドAは期待どおりに保存されます。 「A」を挿入した場合、最初の文字の後に文字列の途中の終わりを示す特殊文字が提供されますが、同じスペースを占めます。

フィールドCは、256に相当するバイナリとして保存されます。なぜBではなくCなのでしょうか。 Cは固定長の次の静的フィールドであるため、データベース行の他のすべての静的データと一緒にグループ化されます。

フィールドDはデータベースのメタ情報であり、次の可変長フィールドセクションには1つのフィールドがあることを示しています。

フィールドEも、データベースのメタ情報であり、この特定のフィールドの場合、長さが最大1文字であることを示しています。そうでない場合、データベースはフィールドBが終了し、別の可変長フィールドが開始する場所を認識できないため、この情報は不可欠です。

これはすべて、データベースが可変長フィールドの保存を処理する方法を示しています。 BLOBは、この効果にとって非常に可変長のフィールドです。データベース構造では、1つの行にBLOBの小さい値と大きい値の両方を含めることができますが、ここでは他の要素が関係しています。ディスクは内容を気にせず、1つのチャンクに収まるので、データベースは通常、情報のチャンクを扱います。

データベースは、行を2つに分割する必要なく、同じ数の行を1つのチャンクに収めようとします。それ以外の場合の効果は、ハードドライブに断片化されたファイルがある場合と同じです。 1つのチャンクが読み込まれると、行がその特定のチャンクをオーバーフローすると、ハードドライブは残りのチャンクを別のチャンクで検索する必要があります。さらに悪いことに、データベースは行が可変長であるため、内容を完全に読み取らなければチャンク以上の行を占めることを認識できず、両方のチャンクを一度にフェッチして最適化することはできません。

このロジックに従って、静的な長さのBLOBを作成できたとしても、データベースはチャンクサイズが最小行サイズよりも大きいことを単純に保証できるため、ほとんどの行が確実に実行されないため、この最適化の問題はありません。複数のチャンクに分割する必要があります。もちろん、データベースはこれを実行しません。なぜなら、おそらく必要ないときに貴重なスペースを専用にすることを意味するからです。

比較的少量を扱う場合はBLOBで問題ありませんが、ビデオなどの大きなファイルの場合の一般的な回避策は、ファイルパスをデータベースに保存し、ソフトウェアがほとんど常にファイルのロードを処理するようにすることです。効率的です。

それがそれを説明することを願っています。 :)

5
Neil