すべてのSQLServer 2008文字列列をvarchar(max)にすることに問題はありますか?私の許容文字列サイズはアプリケーションによって管理されます。データベースは私が与えたものを永続化する必要があります。実際に入力されるデータのサイズに関係なく、SQL Server 2008ですべての文字列列がvarchar(max)型であると宣言することで、パフォーマンスが低下しますか?
すべてのSQLServer 2008文字列列をvarchar(max)にすることに問題はありますか?私の許容文字列サイズはアプリケーションによって管理されます。データベースは私が与えたものを永続化する必要があります。実際に入力されるデータのサイズに関係なく、SQL Server 2008ですべての文字列列がvarchar(max)型であると宣言することで、パフォーマンスが低下しますか?
回答:
VARCHAR(MAX)
基本的にSQLServerに「このフィールドに最もよく見える方法で値を格納する」ように指示することにより、SQL Serverは値を通常として格納するかVARCHAR
LOB(ラージオブジェクト)として格納するかを選択します。一般に、格納されている値が8,000バイト未満の場合、SQLServerは値を通常のVARCHAR
型として扱います。
格納された値が大きすぎるその後、カラムは、彼らが他のLOB型のために行うとおりに、LOBページへのページをオフにこぼさ許可(されている場合はtext
、ntext
とimage
) -これは、その後発生した場合、追加のページが読み込みに格納されたデータを読み出すために必要とされています追加のページ(つまり、パフォーマンスが低下する)。ただし、これは、格納されている値が大きすぎる場合にのみ発生します。
実際、SQL Server 2008以降では、固定長のデータ型(例VARCHAR(3,000)
)を使用してもデータが追加のページにオーバーフローする可能性がありますが、これらのページは行オーバーフローデータページと呼ばれ、処理が少し異なります。
短いバージョン:ストレージの観点から、いくつかのに使用VARCHAR(MAX)
することの不利な点はありません。VARCHAR(N)
N
(これはまた、他の可変長フィールドタイプに適用されますNVARCHAR
とVARBINARY
)
参考までに-列にインデックスを作成することはできませんVARCHAR(MAX)
インデックスの幅は900バイトを超えることはできません。したがって、おそらくインデックスを作成することはできません。データが900バイト未満の場合は、varchar(900)を使用してください。
これは1つの欠点です:それが与えるので
Simon Sabinは、しばらく前にこれについて投稿しました。今はそれを取得する時間がありませんが、デフォルトでvarchar(max)を使用すべきではないという結論を彼が思いついたので、検索する必要があります。
編集:Simonはvarchar(max)に関するいくつかの投稿を持っています。以下のコメントのリンクは、これを非常にうまく示しています。最も重要なものはhttp://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspxで、効果について説明していると思います。プランのキャッシュに対するvarchar(max)の影響。一般的な原則は注意することです。maxにする必要がない場合は、maxを使用しないでください。8000文字を超える必要がある場合は、必ず...それを選択してください。
この質問については、特に私が言及していないいくつかの点について説明します。
他のいくつかの理由は、なぜvarchar(8000)
どこにでもない理由についての私の答えでカバーされています。
私は以前に同様の質問をしました。いくつかの興味深い返信がありました。こちらでチェックしてください 幅の広い列を使用することの不利益について話しているサイトが1つありましたが、アプリケーションでデータが制限されている場合、私のテストではそれが反証されました。列にインデックスを作成できないという事実は、私がそれらを常に使用しないことを意味します(個人的には、あまり使用しませんが、その点では少し純粋主義者です)。しかし、それらにあまり保存されていないことを知っているなら、私はそれらがそれほど悪いとは思わない。varchar(max)を含むレコードセット(またはcharまたはvarcharである幅の広い列)の列で並べ替えを行うと、パフォーマンスが低下する可能性があります。これらは(必要に応じて)インデックスによって解決できますが、varchar(max)にインデックスを付けることはできません。将来的に列を保証したい場合は、単に合理的なものに配置してみませんか。たとえば、名前の列は最大ではなく255文字です。
すべての列でvarchar(max)を使用しないようにする別の理由があります。チェック制約を使用するのと同じ理由で(誤ったソフトウェアまたはユーザーエントリによって引き起こされるジャンクでテーブルがいっぱいになるのを避けるため)、意図したよりもはるかに多くのデータを追加する障害のあるプロセスから保護したいと思います。たとえば、誰かまたは何かがCityフィールドに3,000バイトを追加しようとした場合、何かが間違っていることは確実であり、可能な限り早い時点でデバッグするために、プロセスが停止していることを確認します。また、3000バイトの都市名は有効ではない可能性があり、使用しようとするとレポートなどが台無しになることもわかっています。
理想的には、必要なものだけを許可する必要があります。つまり、特定の列(たとえば、ユーザー名列)が20文字を超えることはないと確信している場合、VARCHAR(20)とVARCHAR(MAX)を使用すると、データベースでクエリとデータ構造を最適化できます。
MSDNから:http: //msdn.microsoft.com/en-us/library/ms176089.aspx
Variable-length, non-Unicode character data. n can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes.
これらの列で本当に2 ^ 31-1バイトに近づくことはありますか?