web-dev-qa-db-ja.com

インデックススペースをデータスペースより大きくするのは悪いことですか?

多くの場合、適切なインデックスを持たない大きなテーブルに対してクエリを実行する必要があります。そのため、DBAにそのようなインデックスを作成するように依頼します。彼が最初に行うことは、テーブル統計を見て、インデックス領域のサイズを確認することです。

「インデックスはすでにテーブルよりも大きい」ため、しばしば彼は私に別の解決策を見つけるように言うでしょう。 「本の中で索引を見たことがありますか?それは本自体よりもはるかに小さく、それがテーブルの索引がどうあるべきか」と彼が私に言ったので、彼は索引がデータより小さくなければならないと感じます。

彼の哲学は正しいとは思えませんが、彼はリードDBAであり、私は開発者であるため、彼に挑戦することはできません。クエリにインデックスが必要な場合は、SPを読みにくく、保守できない「回避策」を見つけるのではなく、インデックスを作成するだけでよいと思います。

必要な列のみを選択しています。問題は、日付でフィルター処理しているため、エンジンは必然的にテーブルスキャンを実行して列を一致させることです。クエリは、統計を収集するために1日に1回、夜間に実行されますが、実行には15分かかります(別の難しい規則があります。手順に3分以上かかることはありません)。

DBAはインデックス統計を見せてくれました。そのテーブルには約10のインデックスがあり、そのうち6つしか使用されていませんでした(統計では、そのうち4つにヒットが0でした)。これは、20人を超える開発者が参加する大規模なシステムです。インデックスは何らかの理由で作成され、おそらく使用されていません。

SQL Server 2008をサポートする必要があります。これは、テスト用DBが実行されるためです。しかし、クライアントはすべて2014年と2016年です。

27
hjf

スライド式スイッチのようなインデックス設計を考えてください。この赤い三角形のスイッチノブは、必要な線に沿ってどこにでも移動できます。

Index design decisions

通常、サイズで測定することはありません。通常、インデックスの量で測定しますが、サイズも問題ありません。

DBAは、スイッチが右に離れすぎていると考えているようです。追加したインデックスが多すぎ、削除/更新/挿入の実行速度が遅すぎると思われます。

スイッチがどこにあるかについて議論するのではなく、インデックスの数が多いために発生しているパフォーマンスの問題について尋ねてみてください。おそらく、ユーザーが削除/更新/挿入の速度について不満を言っている、ロックの待機が発生している、またはデータベースのサイズが原因でデータベースのバックアップに苦労している可能性があります。

私の出発点は通常5と5です:テーブルあたり約5インデックス、インデックスあたり約5以下のフィールド。その数に不思議なことはありません。それは、私が両手に5本の指を持っているという事実から来ているので、手を挙げてルールを説明するのは簡単です。

ワークロードが削除/更新/挿入操作に大きく偏っており、ハードウェアの処理能力が足りない場合は、5よりも多くのLESSインデックスが必要になることがあります。

ワークロードがほとんど読み取り専用である場合、またはハードウェアに多大な投資を行っている場合(データベース全体をメモリにキャッシュし、その下にすべてのソリッドステートストレージがある場合など)は、さらに多くのインデックスを作成できる場合があります。

45
Brent Ozar

私はブレントの答えが好きで、賛成しました。でも別の視点を加えたいと思います。私はユーザー、開発者、DBAとして働いていましたが、意見は関係ないと思います。クエリの実行方法と結果の取得にかかる時間を決定するのは、ユーザー(または利害関係者)の責任だと思います。それを実現するために協力するのは、開発者とDBAの責任です。

あなたの会社のDBAの立場がこのトピックの「担当」である場合、彼らはあなたのクエリを分析し、より良いクエリの設計に関する提案をするか、またはパフォーマンスについて答えることができます。

クエリやデータ構造を変更して目標を達成できない場合は、3つの選択肢があると思います。

  1. 遅いデータ検索
  2. データ更新が遅い
  3. その他のハードウェアリソース$$$$

もちろん、すべての状況には複数のビジネスおよびテクノロジーの要因に応じて多くの変数がありますが、3つのオプションはすべてではないにしてもほとんどの場合に当てはまると思います。

5
Joe

また、テーブルに「The Ozar 5」以上のインデックスを作成したいという願望は、おそらくさまざまな種類の読み取りが多いクエリがたくさんあることを示しています。テーブル。

テーブルのクラスター化または非クラスター化 columnstoreインデックス のメリットを享受できることをおそらく示しています

列ストアは、N個の異なるアクセスパスごとに最適なインデックスを持つ代わりに、超高速のスキャンと、不要な列および行セグメントをスキップする機能を提供します。したがって、非常に重要なトランザクション用に少数のBTreeインデックスを作成し、それ以外のものについては列ストアにフォールバックできます。

列ストアインデックスは、SQL Server 2016以降のOLTP負荷の高いワークロードで機能するように設計されています。 リアルタイム運用分析 のドキュメントを参照してください。

インデックスを禁止するには厳しすぎるようです>テーブル。テーブルがめったに変更されない(またはリソースの競合が少ない夜に変更される)場合、さまざまな方法で多くのクエリが実行されると、多くの大きなインデックスを正当化できます。 DBAは、自分が属していない場所に鼻を刺さないように注意する必要もあります。彼があなた/あなたのシステムにギガバイトの制限を与えるならば、彼はそのスペースがどのように使われるかあまり気にすべきではありません。彼が働き過ぎているなら、これが理由かもしれません。

ただし、考慮すべき点がたくさんあります。

  • インデックスが多いと、挿入、更新、削除が遅くなります。したがって、テーブルが大幅に変更される場合は、テーブルの数が多くなりすぎないように注意してください。
  • スペースも問題になる可能性があります。ギガバイトは費用がかかるため(最近ではあまりありません)、バックアップ後の時間が遅くなります(バックアップの方法によって異なります)。
  • ほとんどの深刻なデータベースを監視して、めったにまたはまったく使用されないインデックスを見つけることができます。それらのいくつかをドロップすることを検討してください。
  • 場合によってはインデックスが必要だと思うかもしれませんが、クエリをより詳細に調べると、同じ結果でインデックスを必要とせずに別の方法で調整および書き直すことができます。 Explain Planを使用して、インデックスが使用されているかどうかを確認します。
  • 場合によっては、パフォーマンスに大きな影響を与えることなく、最後の列を複数列のインデックスから削除できます。また、インデックスストレージスペースが小さくなり、いつでもメモリ内に保持/キャッシュされるインデックスが増えるため、クエリが高速になることもあります。
  • 関数ベースのインデックスは、通常のインデックスを置き換えて、より多くのスペースを節約できます。例:姓全体を照会する代わりに、最初の2文字(where substr(surname, 1, 2) = substr(<userinput>, 1, 2) and surname=<userinput>)およびcreate index i on customers(substr(surname,1,2))も照会します。これは十分に高速で、インデックスは小さくなります。
  • データベースは、さまざまなタイプのインデックスをサポートしています。一部のタイプは他よりも少ないスペースを使用します。多分あなたのインデックスのいくつかはより少ないスペースを消費するタイプに変換できますか?最初に、さまざまなインデックスタイプと、それらがどのような状況に適しているか、どのような状況にあるかを理解してください。
  • 頻度の低いバッチジョブが特定のインデックスを必要とする唯一のものである場合は、そのバッチジョブに対してのみインデックスを作成し、後で削除することを検討してください。
1
Kjetil S.