常に(n)varchar(max)
テキスト列に使用する必要がありますか?
いや
SQL Serverの場合、max
代替がない場合にのみデータ型を指定する必要があります。代わりに、正しい基本タイプ(varchar
またはnvarchar
)を選択し、保存するデータに適した明示的な最大長を指定する必要があります。
物理ストレージは、列は次のようにタイプされているかどうか、同一であるvarchar(n)
か、varchar(max)
それが問題ではないので、。
どこでも選択しない理由(n)varchar(max)
は、機能、計画品質、およびパフォーマンスに関係しています。
完全なリストはおそらく実用的ではありませんが、とりわけmax
列は次のとおりです。
特徴
- 最大長を強制するには、個別の制約が必要です
- インデックスのキーにすることはできません(一意の制約もありません)
- オンラインDDLを妨げる可能性があります(インデックスの再構築および新しい非NULL列の追加を含む)
- 列ストアなどの「新しい」機能では一般にサポートされていません
- より具体的な機能と制限については、製品のドキュメントを参照してください。一般的なパターンは、
max
データ型に関して厄介な制限と制限があることです。すべての制限と副作用が文書化されているわけではありません。
性能
- 潜在的に非常に大きなサイズを考慮して、実行エンジンで特別な処理が必要です。通常、これには、ストリーミングインターフェイスで、効率の低いコードパスを使用する必要があります
- 外部コード(およびSSISのような他のSQL Serverコンポーネント)に対して同様の予期しない結果を引き起こす可能性があり、最大2GBのサイズのデータを処理するために準備する必要があります
- メモリ許可の計算では、4000バイト幅であると想定されています。これにより、過剰なメモリ予約が発生し、同時実行性が制限され、貴重なインデックスとデータページがキャッシュメモリから押し出される可能性があります。
- いくつかの重要なパフォーマンス最適化を無効にします
- ロック期間を延長できます
- オプティマイザが(動的ではない)シークプランを選択するのを妨げる可能性があります
- フィルターがスキャンにプッシュされ、残余としてシークされるのを防ぐ
- 変数とパラメーターも
max
列定義に一致するように入力される可能性が高いため、tempdbの圧力と競合(バージョンに依存)が増加する可能性があります。
要約すると、max
指定子を不必要に使用すると微妙な(および望ましくない)副作用が非常に多くなるため、これを行う意味はありません。単一の宣言を使用することの小さな「便利さ」は、一種の補償ではありません。
コンテキスト内の各型を評価し、正しい基本型(varchar
またはnvarchar
)と適切な明示的な長さを使用します。
参考文献: