1

私のアプリケーションには、非常に幅が広​​く、高さが非常に高い複数のテーブルがあります。幅は、さまざまなデータ型 varchar/nvarchar および char/bigint/int/decimal を持つ 10 ~ 20 列から得られる場合があります。私の理解では、SQL のデフォルトのページ サイズは 8k ですが、手動で変更できます。また、その varchar/nvarchar 列はこの制限の対象外であり、多くの場合 (常に?) Row_Overflow と呼ばれるプロセスで別の場所に移動されます。それでも、MS のドキュメントには、Row-Overflowed データがパフォーマンスを低下させると記載されています。「行オーバーフロー データを含む大きなレコードに対して、並べ替えや結合などの他の選択操作をクエリして実行すると、これらのレコードが非同期ではなく同期的に処理されるため、処理時間が遅くなります。」

彼らは、大きな列を結合可能なメタデータ テーブルに移動することを推奨しています。「これは、非同期JOIN操作で照会できます」.

私の質問は、幅の広い列に対応するためにページ サイズを拡大する価値はありますか? また、他にパフォーマンスの問題が発生する可能性はありますか? それを行わず、代わりにテーブルを 1 つ以上のメタデータ テーブルに分割し、テーブルが 100MM レコード範囲のように "大きく" なった場合、分割されたテーブルを結合することは利点をはるかに上回りませんか? また、SQL Server がシングル コア マシン (または SQL Azure) にある場合、私の理解では、並列処理が無効になっているため、結合が非同期ではなくなることを考えると、テーブル イントロ パーティションを移動する利点もなくなりますか? 他にお勧めの戦略はありますか?

編集:以下の素晴らしいコメントといくつかの追加の読書 (私が最初に行うべきだった) によると、SQL Server のページ サイズを手動で変更することはできません。また、関連する SO 投稿: SQL Server のページ サイズを変更するにはどうすればよいですか? . @remus-rusanu からの追加の素晴らしい回答

4

3 に答える 3

6

ページサイズは変更できません。

varchar(x) および (MAX) は、必要に応じて行外に移動されます。つまり、ページ自体に十分なスペースがありません。大きな値がたくさんある場合は、それらを他のテーブルに移動してから、ベース テーブルに結合する方が効果的です。特に、そのデータを常にクエリしているわけではない場合はなおさらです。

その行外データを同期的および非同期的に読み取るという概念はありません。クエリを実行すると、同期的に実行されます。並列化があるかもしれませんが、それはまったく別のものであり、この場合は影響を受けません。

編集: より実用的なアドバイスを提供するには、スキーマといくつかの現実的なデータ特性を示す必要があります。

于 2012-04-30T19:28:05.020 に答える
3

私の理解では、SQL のデフォルトのページ サイズは 8k ですが、手動で変更できます。

「大きなページ」の設定は、データベースのページ サイズを変更するのではなく、メモリの割り当てを参照します。SQL Server とラージ ページの説明を参照してください。あなたの理解が少しずれていると思います。

一般的な非具体的なアドバイスとして、幅の広い固定長の列の場合、最適な戦略はrow-compressionを展開することです。の場合nvarcharUnicode 圧縮が大いに役立ちます。具体的なアドバイスについては、測定する必要があります。発生した正確なパフォーマンスの問題は何ですか? どのように測定しましたか?Waits and Queuesのような方法論を使用してボトルネックを特定しましたか?行サイズと行外ストレージが問題であると確信していますか? あなたは他の「方法論」を使ったように思えます...

于 2012-04-30T19:43:50.320 に答える
1
  • デフォルトの 8k ページ サイズは変更できません
  • varcharnvarchar他のフィールドと同じように扱われます。ただし、ページ(max)のサイズを拡張できるため、少し異なって格納されることを意味しますが、別のデータ型ではできないためです。

たとえば、次のステートメントを実行しようとすると、次のようになります。

create table test_varchars(
  a varchar(8000),
  b varchar(8001),
  c nvarchar(4000),
  d nvarchar(4001)
)

列 a と c はどちらも最大 8000 バイトの長さであるため、問題ありません。

ただし、列 b と d で次のエラーが発生します。

列 'b' に指定されたサイズ (8001) は、すべてのデータ型に許可されている最大値 (8000) を超えています。
パラメータ 'd' に指定されたサイズ (4001) が、許可されている最大値 (4000) を超えています。

どちらも 8000 バイトの制限を超えているためです。(またはnの前のは Unicode を意味し、2 倍のスペースを占めることに注意してください)varcharchar

于 2012-04-30T19:55:30.140 に答える