web-dev-qa-db-ja.com

大きなテーブルにDDLを変更し、サーバーとオブジェクトの競合を最小限に抑える方法は?

最近継承したデータベースで、多数の大きなテーブル(それぞれに数十億から数百億のレコード)を使用しています。データベースのユースケースに役立ついくつかの明確なDDL変更を確認しましたが、データベースが非常に最小限の競合しかできないため、それらを実装するのは困難です。 (基本的に、重いクエリが1〜2分以上実行されている場合は、強制終了する必要があります。)

メンテナンスの時間帯であっても、これらの変更は非常に長くなり、割り当てられた時間を超過します(実際には稼働時間がないため、最大で1時間)。

加えたい変更の種類は、インデックスの作成、永続的な計算列の追加、インデックス付きビューの作成、および一般的なインデックスの調整です。これらの操作のいずれかを繰り返し実行し、反復間で一時停止する方法があった場合、バックログが構築される代わりに、少なくとも他のプロセスの実行を許可できるため、時間がかかる合計時間を回避できます。

私が考えることができる唯一のアイデアは、DDLを変更できる別のサーバーにデータベースのコピーを維持し、アプリケーションをそのサーバーに再ポイントする場合です。次に、最初のサーバーをDDLの変更で更新して同期させます。次に、更新を行う必要があるときに、このプロセスを繰り返すことができます。

編集:SQL Server 2016 Enterprise Editionを使用しています。

2
J.D.

大きなインデックスの作成に役立つことがわかった最良のことは、(1)十分なRAMを確保し、(2)インデックスの作成が開始するまでに時間がかかること、(3)インデックスフィールドのSELECT...INTOを実行することです。インデックスを作成する直前に、目的のインデックス順序のORDER BYを持つ一時テーブル。これによりできる場合があります場合によっては、プロセスが最大75%高速化されます(これまでのところ完全には特定していません)。

さらに、それ以外の場合は未使用の高性能ドライブまたはドライブアレイ(SSDを推奨)を追加して、そのドライブアレイのファイルグループにインデックスを作成できる場合、インデックス作成のパフォーマンスが大幅に向上します。

既存のインデックスを変更するには、上記のヒントを使用して新しいインデックスを作成し、新しいインデックスでのインデックスの使用状況をしばらく調べた後、既存のインデックスを削除します。 (なぜですか?すべきのパフォーマンスが向上するように一部のインデックスを変更しましたが、全体的なパフォーマンスの低下を検出しました。新しいインデックスを作成し、SQL Serverがそれを使用するかどうかを監視したり、インデックスを強制的に実行してパフォーマンスを確認したりできます。)

もちろん、SQL Server 2016 EEがあるので、ONLINE = ONオプションを使用します。これにより、インデックス作成時のロックが最小限に抑えられ、非クラスター化インデックスの作成または変更に最適です。クラスター化インデックスはテーブル全体を再編成するため、何が発生しても時間がかかります。

4
Laughing Vergil

私が考えることができる唯一のアイデアは、DDLを変更できる別のサーバーにデータベースのコピーを維持し、アプリケーションをそのサーバーに再ポイントする場合です。

代わりに、新しいテーブルを作成し、それを既存のテーブルから段階的にロードすることを検討してください(変更追跡やトリガーなどが役立つ場合があります)。次に、短いウィンドウで最終的な同期を実行し、テーブルの名前を変更します。