「縮小」しようとしているこの大規模なデータベース(> 1TB)があります。データベースは1つの主要なエンティティを中心に展開します。「訪問」と呼びましょう。議論のために、それは医療行為のためのデータベースであるとしましょう。
手順、年次、フォローアップ、予防接種など、合計30の訪問「タイプ」があり、それぞれが「訪問」のサブテーブルです。 「visit_immuno」。
データベースは2000年以降約12年分のデータを蓄積しています。約3年分のデータを「ライブ」バージョンで保持し、残りを「old_data」データベースでライブにすることを誰かが提案しました。日付は正規化されているため、「訪問」テーブルにのみ格納されます。 Visitテーブルには、ROWVERSION
列とBIGINT
疑似ID(クラスター化)列も含まれています。すべての意図と目的で、クラスタリングキーにSEQUENCE(SQL Server 2012 Enterprise)が入力されているとしましょう。cid
という名前を付けます。
_visit.date
_は常にクラスタリングキーと同じ順序であるとは限りません。たとえば、医師が長期の通院を続け、データの「ブリーフケース」を返した場合、メインテーブルにマージされます。 「visit」テーブルにいくつかの更新があり、ROWVERSION
列がcid
およびdate
列の両方と同期しなくなります-簡単に言えば、このため、ROWVERSION
もcid
も適切なパーティションキーを作成しません。
「ライブ」からデータを削除するためのビジネスルールは、_visit.date
_が36か月以上である必要がありますand子_visit_payment
_レコードが存在する必要があります。また、「old_data」データベースには、_visit%
_以外の基本テーブルは含まれていません。
したがって、次のようになります。
ライブDB(毎日使用)-すべてのテーブルOld-Data DB-_visit%
_テーブルの古いデータ
この提案では、_Live DB
_(_visit%
_を除く)のすべてのベーステーブルにSynonymsを含むシェルであるCombined DBが必要です- Views 2つのデータベースの_visit%
_テーブル全体のUNION ALL。
同じインデックスが_Old-Data
_ DBで作成されると仮定すると、クエリはUNION-ALL Viewsで適切に実行されますか? UNION-ALL Viewsの実行プランに影響を与える可能性のあるクエリパターンの種類は何ですか?
便宜上、ライブデータベースはLiveDb
と呼ばれ、アーカイブデータベースはArchiveDb
と呼ばれると想定します
LiveDb
データベースのテーブルを指すArchiveDb
にUNION ALLビューを追加します(シノニムと組み合わせたdbを実行する必要はありません)visit.date
の「パーティション」と、この列がvisit_payments
にない場合は、これも非正規化します(これにより、同じ場所にある結合のパフォーマンスが向上します)。LiveDb
に保持して、小さいテーブルへのすべての結合がローカルに保持されるようにしますvisit.date
の範囲を記述するLiveDb
とArchiveDb
の両方のテーブルにCHECK制約を追加します。これは、オプティマイザが列visit.data
を含むシークとスキャンの両方からアーカイブテーブルを削除するのに役立ちます。この制約は定期的に更新する必要があります。visit.data
でフィルタリングするWHERE基準を追加します。これは、チェック制約ですでに指定したヒントに追加されます。これにより、フィルターが押し下げられる可能性が最大になりますAchiveDb
がSIMPLEリカバリーモードになっていない場合は、それを設定することを検討してください。 ArchiveDb
のトランザクションログバックアップが必要になることはほとんどありません。LiveDb
とArchiveDb
の間でデータを移動するときに、INSERT ... WITH(TABLOCK)SELECT ... WITH(ROWLOCK)を使用して、宛先でのロギングを最小限に抑えます上記のすべては、オプティマイザがシークとスキャンからアーカイブテーブルを削除することを保証するものではありませんが、可能性が高くなります。
相殺が起こらないとき。これらはあなたが見るかもしれない効果です(このリストは不完全かもしれません)。シークの場合、すべてのクエリで追加のシークを取得します(これによりIOPSが増加します)。スキャンの場合、アーカイブテーブルとライブテーブルの両方をスキャンしてしまう可能性があるため、パフォーマンスに悪影響を与える可能性があります。オプティマイザーを作動させる一般的な方法は次のとおりです。
visit%
テーブルを結合して、結合基準にvisit.data
を含めない場合(これが非正規化する理由です)。このため、クエリの一部を変更することができますvisit.data
と別のテーブル(日付のディメンションなど)とのハッシュ結合を取得すると、テーブルが適切に削除されない場合がありますvisit.data
、たとえばビューのキーを直接検索します。最後のシナリオでは、cid
に別のチェック制約を追加することで、最悪の影響から身を守ることができます(可能な場合)。テーブルの行の日付と進行に関して、cid
のシーケンスが「クリーン」ではないことを説明しました。しかし、「このvisit.data
なので、この数値を超えるcid
はありません」などの情報を含むテーブルを維持できますか?これにより、追加の制約が発生する可能性があります。
もう1つ注意すべき点は、パーティションビューにクエリを実行すると、並列クエリがより多くのスレッドを生成する可能性があることです(両方の「サブテーブル」が同じ並列最適化に公開されるため)。そのため、サーバーでのMAXDOPまたは並列クエリを制限することができます。
ちなみに、クエリをよく知っている場合は、2つのデータベースに同じインデックスが必要ない場合もあります(これにより、100%確実にテーブルを削除できると想定しています)。 ArchiveDb
の列ストアの使用を検討することもできます。