免責事項
少し前にテーブルデザインのアイデアを思いつきました。最近の歴史の中で、私は「オーバーエンジニアリング」の習慣を持っているか、ソリューションを「オーバーオプティマイズ」しようとすることに時間をかけすぎることに気づきました。これは私が解決策を考えすぎており、実際の利益がほとんどないかまったくない余分なオーバーヘッドが発生する場合の1つであると想定しています。
質問
オブジェクト(たとえば、Shipment
table
)について、追跡したいNOTE
varchar(MAX)
データ要素があると仮定します。 NOTE
column
は、データをオーバーフローにプッシュし、row
のサイズを劇的に増加させる機会があります(したがって、rows
に保存できるpage
の数を制限します)。私が理解しているように、これはテーブル全体のさまざまな操作の実行時間に悪影響を及ぼします。
column
ShipmentNote
のtable
として保持する代わりに、column
を別のスタンドアロンShipment
table
にプッシュする必要があるインスタンスはありますか?理論的には、NOTE
column
を別のtable
にプッシュすると、pages
Shipment
のtable
が保存され、Shipment
table
のすべての操作をより効率的に実行できます。 row
サイズが小さくなり、より多くのrows
を同じpage
に収まるようになりました。
(以下のスキーマの例を参照してください):
これが良いアイデアとなる主なユースケースは、次の場合です
Note
column
は通常8000文字を超えています(これは、追加のページングを使い始めたときです)Note
column
はSELECT
操作でのみ返され、JOIN
またはWHERE
の一部として使用されることはほとんどありませんcolumns
の残りのShipment
は、Note
とは関係なく定期的にクエリされます(IE:ほとんどの操作はNote
を利用しません。そのため、JOIN
またはWHERE
条件が[発送]の他のcolumns
で発生します)私が目にしている不利な点(これ以外では、実際にShipment
列の外のNote
テーブルを操作する際に顕著な改善が見られない場合があります):
trigger
に常に何らかの種類の値があることを確認することが不可能になった(または少なくともNOTE
か何かが必要になる)(IE:現在は別のchild table
にあるため、NOTE
がNOT NULL
row
内のすべてのShipment
NOTE
を使用するすべての操作は、正しいレコードで作業していることを確認するためにJOIN
を実行する必要があるため、余分な労力がかかるようになります。あなたがこれについてさえ考えていることは素晴らしいことですが、私はそれをミクロ最適化であると考えます。 SQL Serverには、NVARCHAR(MAX)
を処理するための最適化がすでに組み込まれているため、一般的に、問題が発生するまで、推測する必要はありません。ただし、質問を読んだときに頭に浮かんだ主な2つのポイントがあります。
1つ目は(最後のポイントで触れたように)、SQL Serverにページとデータ自体を最適化させるよりも、データを別のテーブルに分割することで実際にパフォーマンスが向上するかどうかです。今のところ、確固たる証拠はありませんが、そうではないと思います。その理由は、お伝えしたように、データは通常8000バイトを超えているため、とにかくNoteテーブルのLOBページに移動されるためです。認識された問題を1つのテーブルから別のテーブルに移動するだけです。データをフェッチする必要がある場合にJOIN
を実行するオーバーヘッドを追加すると、最初よりも少し悪い結果になる可能性があります。
次に、データベースのデザインで質問にタグを付けたとき、私の実際の推奨事項は、あなたがdoノートを別のテーブルに分割することです。ただし、私の推論は、パフォーマンスの最適化ではなく、より具体的にはアプリケーションに柔軟性を追加することに基づいています。貨物に複数のメモを添付する必要がある可能性が高いです(たとえば、輸送中に遅延した場合、または顧客が電話をかけた場合など)。実際の出荷自体に関するメモがある場合、データを複製せずにこれを行うことは困難になります。それを独自のテーブルに抽出すると、出荷に複数のメモを割り当て、誰がいつ入力したかを追跡できます。これにより、アプリケーションとデータベースがより柔軟になります。
最適化したい場合は、誰かが特にそれらを表示したい場合(アプリケーションに専用フォームを用意するなど)を除いて、ノートをクエリする必要をなくすことをお勧めします。そうすれば、誰かが明示的にデータを表示したい場合にのみ、結合/検索を実行する必要があります。ノートを別のテーブルに外部化していなくても、列が不要な場合にクエリに含めないことで、SQL ServerがLOBページを読み取る必要がなくなります。可能であれば、マイクロレベルで最適化する前に、必要な最小限の情報を返すように常にクエリを最適化します。
単純な答えは「ノー」です。ただし、常にテーブルのすべての列をフェッチするアプリケーションがあり、シップメントを照会するたびにメモが取得されないようにする必要がある場合を除きます。
行にメモを保存しないようにSQL Serverに指示し、テーブルオプション '大きな値の型から行を外す' を使用して別のLOBへのポインターを使用し、プッシュすることもできる場合 CREATE TABLE でTEXTIMAGE_ONオプションを設定して、これらのLOBを別のファイルグループに追加します。