database - 高速 - 複数回フィールドを定義することはできません access




データベースインデックスの数が多すぎますか? (12)

私はかなり大きなOracleデータベースを持つプロジェクトに取り組んでいます(私の質問は他のデータベースにも同様です)。 私たちはユーザーがフィールドの可能なあらゆる組み合わせを検索できるWebインターフェイスを持っています。

これらの検索を高速化するために、ユーザーが一般的に検索するフィールドやフィールドの組み合わせにインデックスを追加しています。 ただし、お客様がこのソフトウェアをどのように使用するかはわからないため、作成するインデックスを特定するのは難しいです。

スペースは問題ではありません。 私たちは4テラバイトのRAIDドライブを使用しています。 しかし、索引が多すぎるとパフォーマンスが低下する可能性があると私は心配しています。 行が追加、削除、または変更されるたびにこれらの索引を更新する必要があるため、1つの表に数十の索引を作成することをお勧めします。

したがって、どれくらいの数のインデックスが多すぎると考えられますか? 10? 25? 50? または、私は本当に、本当に一般的で明白なケースをカバーし、他のすべてを無視する必要がありますか?


SQL Serverは、どのインデックスが実際に使用されているかを確認するための良いツールを提供します。 この記事( http://www.mssqltips.com/tip.asp?tip=1239では、更新されるインデックスの量とは対照的に、インデックスの使用量に関するより良い見識を得るためのクエリを提供しています。


いくつの列がありますか? 私はいつも、マルチカラムインデックスではなく、シングルカラムインデックスを作るように言われてきました。 列の量よりも索引はなく、IMHO。


これは、テーブル上で発生する操作に依存します。

SELECTの数が多く、変更がほとんどない場合は、好きなようにインデックスを作成します。これらはSELECTステートメントを高速化します。

テーブルがUPDATE、INSERT、DELETEによって大きくヒットした場合、これらの操作のいずれかが行われるたびに変更する必要があるため、多くのインデックスでは非常に遅くなります

言いましたが、何もしないテーブルに無意味なインデックスをたくさん追加することができます。 2つの異なる値を持つ列にBツリー索引を追加すると、データを検索する点で何も追加されないため、無意味です。 列内の値の固有性が高いほど、索引の利点が増えます。


これは実践よりも理論的な疑問です。 昨日、Oracleは11gデータベースで10倍の速さで動作するはずのHP製の専用ストレージを発表したと聞いていましたが、あなたのパフォーマンスに与える影響は、ハードウェア、Oracleのバージョン、インデックスの種類などによって異なります。 あなたのケースでは、いくつかの解決法があります:1.インデックスを大量に(> 20)、毎日(夜間に)再構築します。 これは、テーブルが毎日何千もの更新/削除を取得する場合に特に便利です。 2.テーブルを分割します(データモデルが適用される場合)。 3.新しい/更新されたデータに別のテーブルを使用し、データを結合する夜間のプロセスを実行します。 これには、アプリケーションロジックの変更が必要です。 4.データがこれをサポートしている場合は、IOT(索引構成表)に切り替えます。

もちろん、そのような場合にはさらに多くの解決策があるかもしれません。 私が最初に提案したのは、DBを開発環境にクローンし、ストレステストを実行することです。


データ・ウェアハウスでは、多数の索引を持つことが非常に一般的です。 私は、2百の列を持ち、そのうちの190の索引付けされたファクト表を使って作業しました。

これにはオーバーヘッドがありますが、データウェアハウスでは一般に一度しか行を挿入しないで、更新することはありませんが、何千ものSELECTクエリに参加することができます。列。

最大限の柔軟性を得るために、データ・ウェアハウスは一般に、(圧縮された)btree索引を使用できる高カーディナリティー列を除き、単一列のビットマップ索引を使用します。

インデックスメンテナンスのオーバヘッドは、大部分のブロックへの書き込みと、新しい列がその列の既存の値範囲の「真ん中」に追加されたときにブロック分割に費やされるコストと関連しています。 これは、パーティション分割と、新しいデータのロードをパーティショニングスキームと整合させ、ダイレクトパス挿入を使用することによって軽減できます。

あなたの疑問をより直接的に解決するには、最初は明らかにインデックスを付けるのが良いかもしれませんが、テーブルに対するクエリが有効な場合は、さらにインデックスを追加することを恐れません。


主に読んでいる(そして更新が少ない)場合、索引付けする必要があるすべてのものを索引付けしない理由はありません。 頻繁に更新する場合は、索引の数に注意する必要があります。 ハードな数字はありませんが、物事が減速し始めるときに気付くでしょう。 クラスタ化インデックスは、データに基づいて最も合理的なものであることを確認してください。


実際には、あなたが知っていない限りインデックスを追加しないでください(そして、これは頻繁に使用統計を集めることを意味します)。更新されるより頻繁に使用されます。

その基準を満たしていないインデックスは、使用された奇妙なケースでパフォーマンスペナルティを持っていないということよりも、再構築のためのコストがかかります。


最終的に必要なインデックスの数は、データベースサーバーの上に乗るアプリケーションの動作によって異なります。

一般的には、より多くのインパクトを与えるほど、あなたのインデックスはますます痛いものになります。 挿入を行うたびに、その表を含むすべての索引を更新する必要があります。

アプリケーションの読み込み量がまともであれば、読み込みがほぼ完了していればインデックスを作成することができます。これにより、パフォーマンスは大幅に向上しますが、コストはほとんどかかりません。


私は実際のプロジェクトと実際のMySqlデータベースについて簡単なテストを行いました。 私はすでにこのトピックで答えています: 複数のdb列をインデックスするコストはいくらですか?

しかし、私はここでそれを引用すればより良いと思う:

私は実際のプロジェクトと実際のMySqlデータベースを使って簡単なテストを行いました。

私の結果は次のとおりです。平均インデックス(インデックスの1〜3カラム)をテーブルに追加すると、挿入が2.1%遅くなります。 したがって、20のインデックスを追加すると、挿入が40〜50%遅くなります。 しかし、あなたの選択は10-100倍速くなります。

だから、多くのインデックスを追加してもよろしいですか? - それは依存している:私はあなたに私の結果を与えた - あなたが決める!


私は通常このように進んでいます。

  1. 典型的な日にデータに対して実行された実際のクエリのログを取得します。
  2. 最も重要なクエリが実行計画のインデックスにヒットするようにインデックスを追加します。
  3. 更新や挿入が多いフィールドのインデックス作成を避けてください
  4. いくつかのインデックスの後に、新しいログを取得して繰り返します。

すべての最適化と同様に、要求されたパフォーマンスに達すると停止します(これは明らかに、ポイント0は特定のパフォーマンス要件を取得することを意味します)。


考慮すべき点の1つは、検索の標準的な組み合わせをターゲットにするための索引の作成です。 column1が一般的に検索され、column2が頻繁に使用され、column3がcolumn2とcolumn1で使用されることがある場合、その順序でcolumn1、column2、およびcolumn3のインデックスを使用できます。 1つの索引のみを維持する必要があります。


誰もがあなたに大きな助言をしてくれました。 あなたが前進するにつれ、私はあなたのための提案が追加されました。 ある時点で、最適なインデックス作成戦略を決定する必要があります。 最終的に、PLANNEDの最適な索引付け戦略は、最終的には使用されない索引を作成することになります。 使用されていないインデックスを見つけるための戦略の1つは、インデックスの使用状況を監視することです。 これは次のように行います:

alter index my_index_name monitoring usage;

その後、v $ object_usageを照会することによって、その時点からインデックスが使用されているかどうかを監視できます。 この情報は、「 Oracle Database管理者ガイド」を参照してください

表を更新する前に索引を削除し、索引を再作成するという倉庫管理の戦略を採用している場合は、索引を再度監視用に設定する必要があり、その索引の監視履歴は失われます。





database-design