web-dev-qa-db-ja.com

SQL Serverがフラグメント化されたインデックスを使用するように強制しますか?

非常に大きなテーブル(> 1000万行)で、頻繁にクラッド操作が行われています。適切なインデックスがありますが、すぐに断片化されます。定期的なインデックスの再編成/再構築のメンテナンスプランがないと、インデックスの断片化が簡単に90%を超える可能性があります。

現在、私はこれに対処するために、毎日インデックスを再編成し、毎週再構築しています。断片化を低く抑えるために、フィルファクターなども試しました。

主な問題は、インデックスが断片化しすぎると、SQL Serverがインデックスを無視し、代わりにフルテーブルスキャンを実行することです。そのような場合、そのような大きなテーブルを繰り返しスキャンすることは非常に重いため、アプリケーションをほぼ強制終了します。これらの場合、フラグメント化されたインデックスを使用する方が高速だと確信しています。

断片化に関係なく、SQL Serverにインデックスを使用させる方法はありますか?

7
mikaelnet

インデックスヒント

index hint を使用してそれを行うことができます:

SELECT *
FROM dbo.Users AS u WITH (INDEX = ix_definitely_an_index)
WHERE u.Reputation = 2;

欠点は次のとおりです。

  • 多くのコードを変更する可能性
  • インデックスの名前を変更すると、これは壊れます
  • インデックス定義を変更すると、それはもう使用するのに最適なインデックスではない可能性があります

計画ガイド

プランガイド を使用して、必要なプランを設定することもできます。

欠点は次のとおりです。

  • それは気まぐれです。クエリがまったく同じでない場合、計画が使用されない可能性があります
  • セットアップは大変です。すべてを正確に把握する必要があります
  • インデックスのヒントと同じなので、ええと...それは大雑把です。

クエリストア?

SQL Server 2017を使用しているため、 クエリストアを強制するクエリストア を使用できる場合があります。これはプランガイドを使用するよりもはるかに簡単ですが、 予期しないプラン になる可能性があります。

欠点:

  • 上記と同じもの
  • まだ使用していない場合は、クエリストアを有効にする必要がある
  • 強制計画が失敗しているかどうかを確認するためにクエリストアをクエリする必要がある

代替案

詳細を知らなくても、 parameter sniffing のような他の理由でインデックスの使用が変更されていないか調査したいと思うでしょう。

14
Erik Darling

次回SQL Serverがインデックスを無視するときは、そのインデックスまたはテーブル全体でFULL SCANを使用して統計を更新しようとします。それが機能する場合、断片化は問題ではありません。

また、SQL Serverはプランを選択するときに断片化を考慮しませんが、「内部断片化」が原因でインデックスが大きくなりすぎた場合、インデックスを無視することがあります。インデックスのページ内の空きスペースを確認してください。

1