2016-09-27 8 views
0

BLOBを含む表のSELECT問合せは、BLOB列が含まれていなくても低速です。誰かが理由を説明し、それを回避する方法を教えてもらえますか?私はSQL Server 2012を使用していますが、これは他のディストリビューションでも共通する概念的な問題です。ブロブが選択されていない場合でも、ブロブのあるテーブルでSQLクエリを選択するのが遅いのはなぜですか?

私は同じ問題を示している同じ問題を示しているSQL Server: select on a table that contains a blobですが、マークされた答えはなぜこのようなことが起こっているのかを説明しておらず、どちらも問題の解決方法についての良い示唆を提供していません。

+0

SQL Serverを使用していますか? – jarlh

+0

SQL Server 2012 R2、これは多くのMS SQL Serverバージョンに共通すると思いますが、他のSQLサーバーにも共通していますか? – LIvanov

+0

それはおそらくSQLがテーブルページを簡単にキャッシュすることができず、より頻繁にディスクに移動する必要があるからです。私はあなたがなぜブロブを必要とする場合は、ちょうど結合を行う – Cato

答えて

2

あなたがパフォーマンスのドラッグを解決する方法を求めている場合、あなたが取ることができるいくつかのアプローチがあります。テーブルにインデックスを追加するだけで、レコードセット全体を単純に選択するのではなく、大規模に役立ちます。テーブル上のビューを作成することも役立ちます。表の索引断片化のレベルをチェックすることも価値があります。これは、パフォーマンスが低下し、定期的な保守作業で対処できるためです。 BLOBデータを格納するためのリンクされたテーブルを作成することの提案もまた真に良いものです。

しかし、あなたの質問がなぜ起こっているのかを尋ねるのであれば、これはMS SQL Serverの機能の基本が原因です。本質的にあなたのデータベースと、サーバー上のすべてのデータベースと、ページに分割。96kbのヘッダーを持つ8kbのデータチャンク。各ページは、単一のI/O操作で可能なものを表します。ページは、集められ、8つの連続したページの64kbのコレクション、Exents内にグループ分けされています。したがって、SQL Serverはメガバイトあたり16個のExentsを使用します。いくつかの異なるページタイプがあります。たとえば、データページタイプには「ラージオブジェクト」と呼ばれるものは含まれません。これには、text、image、varbinary(max)、xml dataなどのデータ型も含まれます。これらは、8kbを超える可変長列を格納するためにも使用されます(96バイトのヘッダーも忘れないでください)。

各ページの最後には、空き容量が少なくなります。データベース操作は明らかにこれらのページを常に移動し、大量のI/Oとランダムなレコードへのアクセス/変更を扱うデータベースでは、空き領域の割り当てが大幅に増加する可能性があります。このため、データベース上の空き領域が大幅に増加することがあります。管理スイート内には空き領域を減らすか削除するためのツールが用意されており、基本的にはページやエクステントを再編成します。

ここで私は跳躍をしているかもしれませんが、あなたのテーブルのブロブが8kbを超えると推測しています。 64kbを超えると、複数のページにまたがるだけでなく、実際に複数のエキスにまたがることに注意してください。この結果は、通常のテーブル読取りで大量のI/O要求が発生することになります。 BLOBデータに興味がなくても、サーバーはページとエクセスを読み込んで別のテーブルデータを取得する必要があります。これは、テーブルを構成するページとエキセントが非連続的になるようにトランザクションを増やすことによってのみ合成されます。

"ラージオブジェクト"が使用されている場合、SQL Serverは、データが実際に格納されている場所への24ビットポインタを含むRow-Overflow値を書き込みます。8 KBのページ・サイズを超え、ランダムなトランザクションの影響を受けた8 KBのページ・サイズを超える列がいくつかある場合、サーバーが実行している作業の大半はメモリー内外のページを移動するI/O操作であり、ポインタの読み取り、関連する行データのフェッチなど、すべてが深刻なオーバーヘッドを表します。

+0

良い。だから、 "ラージオブジェクト"が使われているところでは、SQL Serverはラージオブジェクトが実際に格納されている別の場所へのポインタを書きます(私のオブジェクトは50KBから3MBの間です)。では、なぜBLOB参照が指し示す場所にあるものであれ、エンジンのロードは何ですか? BLOBを含まないクエリを作成すると、なぜそれを取得するのですか? BLOBが配置されているExentsに、より多くのデータが含まれているとしたら?それで、最初のものと最後のものだけでなく、それらが連続していてBLOBのスパンが10個あるとすれば、なぜそれをすべて取り出すのですか? – LIvanov

+0

あなた自身の質問に答えました。それらが連続して(または連続的にさえ)保存されているという保証はない。 50kbのオブジェクトが7ページに存在すると仮定しないでください。そのオブジェクトを構成する7ページが2つ、3つ、または7つの異なるエキセントに存在する可能性があります。 –

+0

私は今参照してください。これをクリアしていただきありがとうございます。たぶんあなたの答えに追加して、同じことに遭遇する可能性のある人には完全に明確になるようにしてください:) – LIvanov

2

私は、その後の提案を持って、ので、それができるだけ、あなたのメインテーブルにアイデンティティIDを保存

、アイデンティティIDを持つ別のテーブルにすべてのブロブを持っている - 多分SQLは、表のページをキャッシュすることはできません簡単に、あなたはより頻繁にディスクに行く必要があります。私はなぜ、しかし、なぜ専門家ではありません。

多くの人がデータベースのBLOBS/imagesにぶち壊っています - SQL 2012では、実際のDBではなくオブジェクトをファイル構造に保持するようにDBを構成できるような妥協点があります。それを探してください

+0

これは最善の方法だと思います。これについての理由は何のための質問です。また、現時点で私の会社がこの変更を開始する可能性はないので、私は別のアプローチを探しています。 – LIvanov

関連する問題