web-dev-qa-db-ja.com

再構築後、インデックスの断片化が大幅に増加しました

私はこれをグーグルで調べたところ、一部の人々はインデックスの断片化は問題ではないと言っていることを知っていますが、彼らはそれが問題になるかもしれないシナリオを説明し続けます。私のようなシナリオかもしれません。

約33%が断片化された巨大なテーブル(8600万行)にインデックスがあります。

数日前に、特定のクエリに時間がかかりすぎていることに気付き始めました。クエリがインデックスを使用するように記述されているにもかかわらず、インデックスの1つを使用していないように見えました(インデックスが使用されていないことが間違っている可能性があります)

だから私がやったことの一つはインデックスの断片化を見ることでした。テーブルを何も使用していないときに再構築を行ったのは33%でした(ただし、テストとして、インデックスの再構築と同時にテーブルでクエリを実行した場合-おそらくばかばかしい)。

再構築には約10〜20分かかりました。どういうわけか、私は直後に断片化をチェックしませんでした。翌日チェックしたところ(クエリはまだ遅い)、56.06%に増加したことがわかりました。

Screenshot of fragmentation information

別の再構築を試みると、さらに悪化しますか?代わりに再編成を試みるべきですか? (断片化が30%未満の場合はMicrosoftが再編成し、30%を超える場合は再構築することをMicrosoftが推奨することを読みました)

免責事項:私はここで起こっているいくつかの悪い習慣があるかもしれないことを知っています(テーブルのサイズ、デザイン、または何か)私はこれを作成しませんでした、私はその責任を引き継いだだけです。

編集:別の再構築のリスクがありました。今回はすぐに確認しました。断片化された0.01でした。 10分くらい経ってからもう一度調べたところ、約1%の断片化がありました。約1分間隔で再度確認したところ、徐々に断片化が進んでいます。数時間後、53.55%が断片化されました。

@@versionの出力:

Microsoft SQL Server 2005-9.00.3042.00(X64)
2007年2月10日00:59:02
著作権(c)1988-2005 Microsoft Corporation
Windows NT 6.0のStandard Edition(64ビット)(Build 6001:Service Pack 1)

自動圧縮はonです(データベースのプロパティダイアログボックスに「true」と表示されます)


Edit:質問に追加の詳細を与えるためのいくつかの詳細情報...

毎日一定の時間に、テーブルは約50,000〜100,000行の新しいデータの一括更新を取得します。その日の残りの期間は、更新や新しいレコードはなく、純粋にデータが照会されます。

主キーは「recordid」にあり、自動インクリメントフィールドです。新しい挿入の値はテーブルの他のどの値よりも高いため、インデックス内の既存のデータの間にデータを挟む必要はありません。

ここに問題のインデックスの作成インデックスコードがあります...

USE [EWS]
GO

/****** Object:  Index [IX_AmtoteAccountActivity]    Script Date: 03/03/2016 21:07:14 ******/
CREATE CLUSTERED INDEX [IX_AmtoteAccountActivity] ON [dbo].[AmtoteAccountActivity] 
(
    [AccountNumber] ASC,
    [_Date] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, 
ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

それが重要である/関連している場合(そうであるかどうかはわかりません)は、主キーの作成インデックスコードです...

USE [EWS]
GO

/****** Object:  Index [PK_AmtoteAccountActivity]  Script Date: 03/03/2016 21:10:11 ******/
ALTER TABLE [dbo].[AmtoteAccountActivity] ADD  CONSTRAINT [PK_AmtoteAccountActivity] 
PRIMARY KEY NONCLUSTERED 
(
    [RecordID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]
GO

最後に、@ Shankyと@KookieMonsterが示唆しているように、このデータベースではauto_shrinkがオンになっているため、断片化(再構築後に着実に増加する)が発生していると思います。

2
MrVimes

@KookieMonsterが気づいたように、自動縮小がオンになっています。そして、shrinkコマンドの欠点の1つは、もう一度インデックスをフラグメント化することです。

http://www.sqlskills.com/blogs/paul/why-you-should-not-shrink-your-data-files/

2
Marcin S.

ページの充実度は98.23%です。これは、ページごとに140 ishバイトの空きがあることを意味します。これは最小行サイズより大きいです。したがって、キー範囲の途中に挿入を行うと、おそらく更新も行われ、ページの分割と断片化が発生します。

インデックスには約300万のページがあるため、30%の断片化を取得するには、約100万行に影響を与える必要があります。この大きさで書き込むプロセスはありますか?

0
Michael Green

RecordIDがPKであり、フラグメント化されていない場合は、フロップして、recordIDをクラスター化インデックスにする必要があります。

非クラスター化インデックスとしてIX_AmtoteAccountActivityを使用すると、100%未満のフィルファクターが得られます。これにより、挿入速度も向上します。これは大きなテーブルなので、90%でも断片化が遅くなるので、おかしくはありません。そして、そのインデックスの再構築を毎晩スケジュールするだけです。

0
paparazzo

インデックスを再構築するときは、FILLFACTOR = 90以下に設定する必要があります。デフォルトは0で、100%を意味します。

100%FILLFACTORのテーブルでトランザクション(INSERT、UPDATE、DELETE)を実行すると、ページ分割が発生し、最終的にインデックスの断片化が発生します。

断片化につながる多くの理由があります。詳細をお知らせしますので、ここに記載されているリンクをご確認ください。

https://www.mssqltips.com/sqlservertip/2261/sql-server-fragmentation-storage-basics-and-access-methods-part-1-of-9/

ありがとう

0
Rajesh Ranjan