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


22

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

「インデックスはすでにテーブルよりも大きい」ため、多くの場合、代替ソリューションを見つけるように言われます。彼は、インデックスをデータよりも小さくする必要があると感じています。「本でインデックスを見たことがありますか?本自体よりもはるかに小さいので、テーブルインデックスがどうあるべきか」と私に言ったからです。

彼の哲学は正しいとは思わないが、彼は主任DBAであり、私は開発者だから挑戦できない。クエリにインデックスが必要な場合は、読み取り不可能で維持できないSPを作成する「回避策」を見つけるのではなく、インデックスを作成する必要があります。

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

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

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

回答:


34

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

インデックス設計の決定

私は通常、サイズの観点からそれを測定しません-私は通常、インデックスの量の観点からそれを考えますが、サイズも同様にうまくいくでしょう。

DBAは、スイッチが右に行き過ぎていると考えているようです。インデックスを追加しすぎており、削除/更新/挿入の実行が遅すぎます。

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

私の出発点は通常5と5です。テーブルごとに約5個のインデックスがあり、インデックスごとに約5個以下のフィールドがあります。その数について魔法のようなことは何もありません-それはちょうど私が各手に5本の指を持っているという事実から来ているので、私の手を上げてルールを説明するのは簡単です。

ワークロードが削除/更新/挿入操作に大きく偏っていて、維持するのに十分なハードウェア馬力がない場合、5よりも多くのLESSインデックスが必要になる場合があります。

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


4

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

これはおそらくを示しています、テーブルのクラスター化または非クラスター化列ストアインデックスの恩恵を受けることができることをています。

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

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


3

ブレンツの回答が好きで、それを支持しました。ただし、別の観点を追加したいと思います。私はユーザー、開発者、DBAとして働いてきましたが、意見は関係ないと感じています。クエリの実行方法と結果の取得にかかる時間を決定するのは、ユーザー(または利害関係者)次第だと思います。その後、開発者とDBAが協力してそれを実現します。

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

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

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

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


0

インデックスを禁止するには厳しすぎるようです>テーブル。テーブルがめったに変更されない場合(またはリソースの競合が少ない夜間に変更される場合)、さまざまな方法で多くのクエリが実行される場合、多くの大きなインデックスを正当化できます。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))。これは十分に高速であり、インデックスは小さくなります。
  • データベースはさまざまな種類のインデックスをサポートしています。一部のタイプは、他のタイプよりも少ないスペースを使用します。たぶん、あなたのインデックスのいくつかは、より少ないスペースを消費するタイプに変換できますか?まず、さまざまなインデックスタイプと、それらがどのような状況で良いのか、悪いのかを理解してください。
  • まれなバッチジョブが特定のインデックスを必要とする唯一のものである場合、そのバッチジョブに対してのみそのインデックスを作成し、後で削除することを検討してください。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.