web-dev-qa-db-ja.com

大きなテーブルに非クラスター化インデックスを作成すると、トランザクションログがいっぱいになる

SQL Server 2016を使用して、構造intbigintintvarchar(20)varchar(4000)。サイズは〜13,241,928行です。

create nonclustered index nix_TableName on Schema.TableName (
    Column2 asc, Column3, asc
) include (Column4, Column5) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

問題は、50GBにパーティション化されたドライブ上にあるトランザクションログがすぐにいっぱいになることです。データベースは、DW1、DW2、DW3の3つのノードを持つ可用性グループに配置されています。

クラッシュせずにこのインデックスを作成する最も最適で実用的な方法は何ですか?バッチで行うように、インデックス作成を調整できますか? create nonclustered indexステートメントに含めることができる、見逃しているトリックはありますか?

私は this のドキュメントを見つけました。次に、これらのヒントのいくつかを試します。

テーブルには既にクラスター化列ストアインデックスがあります

さらに、サーバーのアクティビティモニターを確認すると、インデックス作成のプロセスがsuspendedであることがわかります。 wait_typeCXPACKETです。 MAX_DOPを指定していません。

2
gh0st

基になるテーブルが列ストアインデックスであるという事実を私が知る限り、ここではあまり関係ありません。質問に含まれているリンクされたドキュメントには、問題の標準的な修正が既に含まれています。以下は、で評価された可能な修正のリストです

  1. ログファイルのサイズを増やします。これは、将来何らかの理由でインデックスを削除して再作成する必要がある場合に役立ちます。

  2. をセットする SORT_IN_TEMPDBオプションをONに追加。これは知りませんでしたが、tempdbに十分な空き容量がある場合に、このオプションが役立ちます。

  3. ページ圧縮を使用してインデックスを作成します。これにより、トランザクションログに書き込まれるデータの量を減らすことができますが、そのvarchar(4000)列で問題が発生する可能性があります。

  4. 必要なインデックスを使用してテーブルの構造のコピーを作成し、データをバッチで挿入します。これは本番環境での実施が難しく、全体的に非効率的ですが、この方法でインデックスビルドを個別のトランザクションに分割できます。問題が発生した場合は、作成したテーブルの一時コピーを削除してください。

  5. テーブルがパーティション化されている場合は、パーティションスイッチングを使用して、非クラスター化インデックスを一度に1つのパーティションに構築できます。

  6. 復旧モデルを一時的に一括ログに変更します。これはあらゆる種類の問題を引き起こす可能性があるので、これを行うことのすべての影響を完全に理解していることを確認してください。

1
Joe Obbish

ログドライブ用のストレージを追加します。

そのデータベースのメンテナンスを行っていると思います。より多くのスペースがあると、インデックスの再構築が失敗する可能性があります。

50Goは、非常に大きなDBにはそれほど役立ちません。ストレージはそれほど高価ではないので、ログファイルがいっぱいになっているため、DBのダウンによるインシデントからあなたを救うのは価値があります。

ありがとう。

0