SQL大規模テーブルの設計


17

SQL Server 2008のテーブル設計に関する一般的な質問があります。現在、600 GBを超えるテーブルがあり、1日に約3 GBで成長しています。このテーブルには適切な指標がありますが、クエリを実行するときやそのサイズのために、大きなハングアップになりつつあります。問題は、年と月でテーブルを複数のテーブルに分割するか(これにより、他の部門が大規模なデータセットを分割する方法に適合します)、またはSQL Serverに組み込まれたパーティションを活用する必要があります。パーティショニングを使用すると、コードの変更が少なくて済むようです。パーティション分割時に読んだものから、まだ1つのテーブルを照会するだけで、サーバーはデータの取得方法を処理します。複数のテーブルルートを使用する場合、複数のテーブルからデータをプルする必要があります。


1
最適化を行う必要があります:データ型が広すぎる、インデックスが重複している、または未使用など
gbn

おそらく、私はまだ他の最適化のために不幸を過ぎて見ていない。推奨事項はありますか?
HunterX3

回答:


11

「このテーブルには適切な指標がありますが、クエリを実行すると大きなハングアップになります」

SQL Serverがクエリの実行時にパーティションを削除できない場合を除き、パーティション分割だけではクエリのパフォーマンスが向上しません。WHERE句は、パーティション分割の方法と一致する必要があります。パーティション化フィールドとして使用するフィールドは1つだけなので、そのフィールドがWHERE句に含まれていない場合、パーティションがあるにもかかわらずテーブル全体をスキャンする可能性があります。

「そしてそのサイズのためだけに。」

パーティショニングは、特定のメンテナンス操作を簡単にすることができますが、パーティションごとに実行できないことはまだあります。インデックスのメンテナンスと統計の更新が問題を引き起こしている場合は、設計をアーカイブテーブルとライブ更新テーブルに分割することをお勧めします。ライブテーブルからアーカイブテーブルに定期的にデータを移動する必要がある場合は、それを行い、100%のFILL FACTORでインデックスを再構築し、フルスキャンで統計情報を更新してから、そのファイルグループを読み取り専用に設定します。パーティション化はアーカイブテーブルのロードに役立ちますが、ライブテーブルのパーティション化はできない場合があります。(ここではいくつかの高度な概念を、あたかもそれが迅速かつ簡単であるかのように投げかけていますが、ここでは背景をいくつかスケッチしています。)

「パーティショニングを使用すると、コードの変更が少なくて済むようです。」

ちょっと-一見するとそのように見えますが、それ以上に入ると、分割ビューのようなオプションがあります。既存のテーブルの名前を変更し、その場所にビューを配置してから、アプリを変更せずに、基礎となるテーブルに独自の変更を加え(および複数のテーブルを追加)できます。

ここで、パーティション分割の落とし穴について詳しく説明しました。

http://www.brentozar.com/archive/2008/06/sql-server-partitioning-not-the-answer-to-everything/


3
その記事からのお気に入りの引用は、間違いなく「パーティション関数とスキームは間違って設計されやすい」です。
マークストーリースミス

7

分離したパーティション分割で十分な場合もありますが、パーティション分割されたビューと複数のテーブルと組み合わせることで、より良い結果が得られる場合があります。クエリと成長のパターンに大きく依存します。

パーティション化の現在の制限は、列統計がパーティションレベルではなくテーブルでのみ維持されることです。より正確な統計情報の恩恵を受けるクエリのパターンがある場合、テーブルパーティションをパーティションビューと組み合わせることで、パフォーマンスが大幅に向上する可能性があります。

データの性質が月ごと、年ごとに異なる場合、パーティションビューも役立ちます。Product.ProductIdの使用範囲に年々一貫性がほとんどないように、製品ラインを絶えず変更している小売業者を想像してください。単一の注文/注文詳細テーブル、したがって単一の統計ヒストグラムを使用すると、統計はクエリオプティマイザーにほとんど提供されません。1年ごとのテーブル(Order_2010、Order_2011、OrderLine_2010、OrderLine_2011)を月ごとにパーティション化し、パーティションビュー(Order、OrderLine)と組み合わせることで、より詳細で潜在的に有用な統計をオプティマイザーに提供します。

比較的少ない労力でテーブルのパーティション分割を導入できるので、そこから始めて影響を測定し、後でパーティション分割ビューが追加の労力に見合うかどうかを評価します。

Kimberly Trippは、多くのガイダンスとパーティションに関するホワイトペーパーを公開しており、これらは一般的にこのトピックを読む必要があると考えられています。Kendra Littleには、優れた資料と他の記事の有用な参照リストもあります。

パフォーマンスは、通常、人々がパーティション分割を検討する最大の理由です。個人的には、回復時間の改善はVLDBと同等以上のメリットがあると考えています。開始する前に、部分的な可用性と断片的な復元を理解するために少し時間をかけてください。

ネットワーク経由でバックアップを送信するという理想的ではないが珍しいプロセスがある場合、現在の600GBの3時間の復元時間を見ているかもしれません。1.5TBに違反した1年で、問題が発生しました。


1
+1「列統計はテーブルでのみ維持されます」ので、キンバリーとケンドラへのリンクでもう一度+1できたらいいのにと思います。
マットM

1

あなたが言ったように、ここには2つのオプションがあります:

  1. 複数のテーブルを活用する
  2. パーティショニングを活用する

1を使用すると、これらのテーブルをすべて結合するVIEWを作成し、新しく作成されたテーブルを含めるように更新できます。これは本当にパーティション分割をエミュレートする方法だと思います。この方法の長所には、SQL ServerのEnterprise Editionが不要なことが含まれます。

2を使用すると、インデックスをパーティションに合わせて、パーティションを別のストレージに合わせることができます。パーティション関数とパーティションスキームを設定した後、パーティションを分割またはマージするときにこれが行われます。この方法の利点は、レコードを新しいテーブルに手動で移動する必要がないことです。パーティション関数とパーティションスキームがこれを処理するためです。さらに、あなたが言ったように、データにアクセスするために必要なコード変更はほとんどありません。

Enterprise Editionをお持ちの場合は、パーティション分割を確認してください。どれほど複雑に見えても、それほど悪くはありません。そうでない場合、パーティショニングはオプションではありません。

パーティションテーブルの作成

パーティションテーブルの変更

データのサブセットを管理するためのパーティションの設計

お役に立てれば、

マット


0

あなたの質問から、履歴データ(ログ)を保存しているように見えますが、ストレージルームの問題ではなく、クエリの速度に制限があるようです。私にとってパーティションは役に立ちません。

適切なインデックスがあると言う場合、日付フィールドにインデックスが含まれていますか?Postgresでtrunc(timestamp、day)のインデックスを使用すると、良い結果が得られました。次に、他の操作の前日にすべてのクエリが選択されるようにする必要があります。タイムゾーンフィールドを持つタイムスタンプはインデックスに登録できないため(タイムゾーンに応じて「移動する」ため)、インデックスを作成するには「固定」タイムスタンプが必要です。


私たちのインデックスは、どのフィールドが最も使用されているかに基づいています。クラスター化されたものが1つ、クラスター化されていないものが2つあり、どちらも広告どおりに機能しているようです。私はそれが問題だと思います。
HunterX3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.