web-dev-qa-db-ja.com

SQLパフォーマンス:NVarChar(200)の代わりにNVarchar(MAX)を使用するとパフォーマンスに影響がありますか

(小さい)最大サイズを与えるのではなく、nvarchar(max)型の列を定義することに不利な点があるかどうか疑問に思っています。

列の値が4 KBを超える場合、残りのデータが「オーバーフロー」領域に追加されることをどこかで読みましたが、これは問題ありません。

私はほとんどの場合テキストが数行になるテーブルを作成していますが、下限を設定し、検証を追加してその制限を超えないようにすることに利点があるかどうか疑問に思っていました。

Nvarchar(max)列を使用したインデックスの作成に制限はありますか、またはサイズ制限の制限を追加する必要があるために支払うものはありますか?

ありがとう!

37
willvv

厳密に言えば、MAX型は常に非MAX型よりも少し遅くなります varchar(max)とvarchar(N)のパフォーマンス比較 を参照してください。しかし、この違いは実際には決して目に見えるものではなく、IOによって駆動される全体的なパフォーマンスのノイズになるだけです。

最大の関心事は、MAXと非MAXのパフォーマンスではありません。質問に注意する必要があります。この列には8000バイトを超える数を格納する必要がある可能性がありますか?答えが「はい」の場合でも、非常にありそうもない「はい」の場合でも、その答えは明らかです。MAXタイプを使用すると、後でこの列をMAXタイプに変換する手間が、非MAXタイプのパフォーマンス上の小さなメリットに見合う価値がなくなります。

その他の懸念事項(その列にインデックスを付ける可能性、MAX列のあるテーブルではONLINEインデックス操作が利用できないこと)は、Denisの回答で既に対処されています。

ところで、オーバーフロー領域にデータが残っている4KBを超える列に関する情報は間違っています。正しい情報は Table and Index Organization にあります。

ROW_OVERFLOW_DATAアロケーションユニット

テーブル(ヒープまたはクラスター化テーブル)、インデックス、またはインデックス付きビューで使用されるすべてのパーティションに対して、ROW_OVERFLOW_DATAアロケーションユニットが1つあります。このアロケーションユニットには、IN_ROW_DATAアロケーションユニットの可変長列(varchar、nvarchar、varbinary、またはsql_variant)を持つデータ行が8 KBの行サイズ制限を超えるまで、ゼロ(0)ページが含まれます。サイズ制限に達すると、SQL Serverは最大幅の列をその行からROW_OVERFLOW_DATAアロケーションユニットのページに移動します。このオフローデータへの24バイトのポインタは、元のページに保持されます。

したがって、4KBを超える列ではなく、ページの空き領域に収まらず、「残り」ではない行が列全体になります。

35
Remus Rusanu

900バイトを超える列にはインデックスを作成できません。ラージオブジェクト(LOB)データ型の列ntext、text、varchar(max)、nvarchar(max)、varbinary(max)、xml、またはimageの列は、インデックスのキー列として指定できません

ただし、included columns

Text、ntext、およびimageを除くすべてのデータ型が許可されます。指定された非キー列のいずれかがvarchar(max)、nvarchar(max)、またはvarbinary(max)データ型である場合、インデックスをオフラインで作成または再構築する必要があります(ONLINE = OFF)。

18
SQLMenace

Nvarchar(max)を選択すると、SQLサーバーエンジンによって自動的に適応される実行プランの最適化にも影響する可能性があります。

3
Farshid