私は、BLOBが別のテーブルにあるだけでなく、データベースにあるべきではないことに同意しません。ファイルがディスク上に存在する場所へのポインタを保存し、データベースから取得します...
(私にとって)それらが引き起こす主な問題は、インデックス作成にあります。クエリプランでXMLを使用します。誰もが理解しているため、テーブルを作成しましょう。
SELECT TOP 1000
ID = IDENTITY(INT,1,1),
deq.query_plan
INTO dbo.index_test
FROM sys.dm_exec_cached_plans AS dec
CROSS APPLY sys.dm_exec_query_plan(dec.plan_handle) AS deq
ALTER TABLE dbo.index_test ADD CONSTRAINT pk_id PRIMARY KEY CLUSTERED (ID)
それはわずか1000行ですが、サイズを確認しています ...
sp_BlitzIndex @DatabaseName = 'StackOverflow', @SchemaName = 'dbo', @TableName = 'index_test'
わずか1000行で40 MBを超えています。1000行ごとに40 MBを追加すると仮定すると、それは非常にいものになります。100万行をヒットするとどうなりますか?約1 TBのデータです。
必要性は、あなたのクラスタ化インデックスを使用することを任意のクエリは現在メモリにそのBLOBデータのすべてを読み込む必要があり明確化: BLOBデータ列が参照されたとき。
BLOBを保存するよりも、SQL Serverのメモリを使用するより良い方法を考えられますか?確かにできるから。
非クラスター化インデックスに拡張する:
CREATE INDEX ix_noblob ON dbo.index_test (ID)
CREATE INDEX ix_returnoftheblob ON dbo.index_test (ID) INCLUDE (query_plan)
通常のクエリでクラスター化インデックスを回避できるように、非クラスター化インデックスを設計してBLOB列を大幅に回避できますが、そのBLOB列が必要になるとすぐにクラスター化インデックスが必要になります。
INCLUDED
キールックアップのシナリオを回避するために非クラスター化インデックスに列として追加すると、巨大な非クラスター化インデックスになります。
彼らが引き起こすより多くの問題:
- 誰もが実行している場合は
SELECT *
、クエリを、彼らはすべてのことBLOBデータを取得します。
- バックアップと復元でスペースを占有し、速度が低下します
DBCC CHECKDB
あなたは腐敗をチェックしていることを知っているので、彼らは遅くなりますか?
- また、インデックスのメンテナンスを行うと、速度も低下します。
お役に立てれば!