120

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

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

スペースは問題ではありません。4テラバイトのRAIDドライブがあり、そのほんの一部しか使用していません。ただし、インデックスが多すぎるとパフォーマンスが低下する可能性があるのではないかと心配しています。これらのインデックスは、行が追加、削除、または変更されるたびに更新する必要があるため、1つのテーブルに数十のインデックスを配置するのは悪い考えだと思います。

では、いくつのインデックスが多すぎると見なされますか?10?25?50?それとも、本当に、本当に一般的で明白なケースをカバーし、他のすべてを無視する必要がありますか?

4

17 に答える 17

96

これは、テーブルで発生する操作によって異なります。

SELECTが多く、変更がほとんどない場合は、必要なものすべてにインデックスを付けます。これらにより、(潜在的に)SELECTステートメントが高速化されます。

テーブルがUPDATE、INSERT + DELETEの影響を大きく受けている場合、これらの操作のいずれかが実行されるたびにすべてを変更する必要があるため、これらは多くのインデックスで非常に遅くなります。

そうは言っても、何もしないテーブルに無意味なインデックスをたくさん追加できることは明らかです。2つの異なる値を持つ列にBツリーインデックスを追加しても、データの検索に関しては何も追加されないため、意味がありません。列の値が一意であるほど、インデックスのメリットが大きくなります。

于 2008-09-26T18:52:53.643 に答える
47

私は通常、このように進めます。

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

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

于 2008-09-26T18:58:28.450 に答える
26

他の誰もがあなたに素晴らしいアドバイスをくれています。先に進むにあたり、追加の提案があります。ある時点で、最善の索引付け戦略について決定を下さなければなりません。ただし、最終的には、最適な PLANNED インデックス作成戦略でも、最終的には使用されないインデックスを作成してしまう可能性があります。使用されていないインデックスを見つける方法の 1 つは、インデックスの使用状況を監視することです。これは次のように行います:-

alter index my_index_name monitoring usage;

その後、v$object_usage をクエリすることで、その時点からインデックスが使用されているかどうかを監視できます。これに関する情報は、『Oracle® Database 管理者ガイド』に記載されています。

テーブルを更新する前にインデックスを削除してから再作成するというウェアハウス戦略を採用している場合は、監視用にインデックスを再度設定する必要があり、そのインデックスの監視履歴が失われることに注意してください。

于 2008-09-26T21:41:10.773 に答える
14

データ ウェアハウスでは、多数のインデックスを持つことは非常に一般的です。私は、200 列と 190 列のインデックスが作成されたファクト テーブルを使用してきました。

これにはオーバーヘッドがありますが、データ ウェアハウスでは通常、行を 1 回だけ挿入し、更新することはありませんが、何千もの SELECT クエリに参加できることを理解する必要があります。列。

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

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

あなたの質問にもっと直接的に対処するには、最初は明らかなものにインデックスを付けても問題ないと思いますが、テーブルに対するクエリが役立つ場合は、インデックスを追加することを恐れないでください。

于 2008-09-26T19:37:22.193 に答える
12

シンプルさについてのアインシュタインの言葉を借りれば、インデックスは必要な数だけ追加し、それ以上追加する必要はありません。

ただし、真剣に、データをテーブルに追加するたびに、追加するすべてのインデックスをメンテナンスする必要があります。主に読み取り専用のテーブルでは、多数のインデックスが適しています。非常に動的なテーブルでは、少ないほど良いです。

私のアドバイスは、一般的で明白なケースをカバーし、特定のテーブルからデータを取得する際により多くの速度が必要な問題に遭遇したときに、その時点でインデックスを評価して追加することです。

また、数か月ごとにインデックス作成スキームを再評価して、インデックス作成が必要な新しいものがないか、または作成したインデックスのうち、何にも使用されておらず、削除する必要があるかどうかを確認することをお勧めします。 .

于 2008-09-26T18:56:33.757 に答える
6

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

しかし、ここで引用するともっと良いと思います。

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

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

では、多くのインデックスを追加しても大丈夫ですか?-それは異なります:)私はあなたに私の結果を与えました-あなたが決める!

于 2010-02-08T00:51:56.347 に答える
6

他のすべての人が提起したポイントに加えて、Cost Based Optimizer は、考慮すべき組み合わせが増えるため、より多くのインデックスがある場合、SQL ステートメントの計画を作成するときにコストが発生します。これは、バインド変数を正しく使用して SQL ステートメントが SQL キャッシュに残るようにすることで削減できます。その後、Oracle はソフト解析を実行し、前回見つけた計画を再利用できます。

いつものように、単純なことは何もありません。歪んだ列とヒストグラムが関係している場合、これは悪い考えです。

私たちの Web アプリケーションでは、許可する検索の組み合わせを制限する傾向があります。そうしないと、文字通りすべての組み合わせのパフォーマンスをテストして、誰かがいつか発見する潜在的な問題がないことを確認する必要があります。また、何か問題が発生した場合にアプリケーションの他の場所で問題が発生するのを防ぐために、リソース制限も実装しました。

于 2008-10-08T08:19:07.803 に答える
3

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

一般に、挿入するほど、インデックスは苦痛になります。挿入を行うたびに、そのテーブルを含むすべてのインデックスを更新する必要があります。

これで、アプリケーションにかなりの量の読み取りがある場合、またはそれ以上の読み取りがある場合は、ほとんどすべての読み取りである場合、非常に少ないコストでパフォーマンスが大幅に向上するため、インデックスが最適です。

于 2008-09-26T18:54:11.843 に答える
3

私の意見では静的な答えはありません。この種のことは「パフォーマンスチューニング」に該当します。

アプリが行うことはすべて主キーによって検索される可能性があります。または、フィールドの無制限の組み合わせに対してクエリが実行され、特定のいずれかがいつでも使用される可能性があるという点で反対の可能性があります。

インデックス作成だけでなく、計算された検索フィールド、テーブルの分割などを含めるように DB を再編成する必要があります。これは、負荷の形状とクエリ パラメータ、クエリによって「実際に」返される必要があるデータの量/種類に大きく依存します。

DB 全体の前にストアド プロシージャ ファサードがある場合、すべてのアドホック クエリを気にする必要がないため、回転が少し簡単になります。または、DB にヒットするクエリの種類を深く理解している可能性があり、チューニングをそれらに限定することができます。

SQL Server の場合、データベース エンジン チューニング アドバイザが役立つことがわかりました。「一般的な」ワークロードを設定すると、インデックスと統計の追加/削除に関する推奨事項を作成できます。他の DB にも、「公式」またはサード パーティの同様のツールがあると確信しています。

于 2008-09-26T18:57:19.217 に答える
3

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

もちろん、そのような場合にはもっと多くの解決策があるかもしれません。あなたへの最初の提案は、DB を開発環境に複製し、それに対していくつかのストレス テストを実行することです。

于 2008-09-26T18:58:23.287 に答える
2

ほとんどの場合、読み取り(およびいくつかの更新)を行う場合は、インデックスを作成する必要があるすべてのものをインデックスに登録しない理由は実際にはありません。頻繁に更新する場合は、インデックスの数に注意する必要があります。確かな数字はありませんが、物事が遅くなり始めると気付くでしょう。クラスタ化されたインデックスが、データに基づいて最も意味のあるものであることを確認してください。

于 2008-09-26T18:54:52.623 に答える
2

インデックスは、基になるテーブルが更新されるときにコストを課します。インデックスは、クエリを高速化するために使用すると利点があります。インデックスごとに、コストとメリットのバランスを取る必要があります。インデックスがない場合、クエリの実行速度はどれくらい遅くなりますか? 速く走ることのメリットは?あなたまたはあなたのユーザーは、インデックスが見つからないときの速度の低下を許容できますか?

更新を完了するのにさらに時間がかかることを許容できますか?

費用と便益を比較する必要があります。それはあなたの状況に特有のものです。「多すぎる」というしきい値を超えるインデックスの魔法の数はありません。

インデックスを保存するために必要なスペースのコストもありますが、あなたの状況ではそれは問題ではないと言いました。ディスク容量がいかに安価になったかを考えると、ほとんどの状況で同じことが言えます。

于 2008-09-26T19:02:59.780 に答える
2

考慮すべきことの 1 つは、検索の標準的な組み合わせを対象とするインデックスを構築することです。column1 が一般的に検索され、column2 が頻繁に使用され、column3 が column2 および column1 と共に使用されることがある場合、column1、column2、および column3 のインデックスをこの順序でこれら 3 つの状況のいずれにも使用できますが、維持する必要があるインデックスは 1 つだけです。

于 2008-09-26T18:55:57.223 に答える
1

柱は何本ありますか?複数列のインデックスではなく、単一列のインデックスを作成するように常に言われてきました。したがって、列の量よりも多くのインデックスはありません、IMHO。

于 2008-09-26T18:55:36.770 に答える
1

つまり、インデックスが更新されるよりもはるかに頻繁に使用されることがわかっている場合 (これは多くの場合、使用状況の統計を収集することを意味します) がない限り、インデックスを追加しないでください。

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

于 2008-09-26T18:56:33.260 に答える
1

SQL サーバーには、実際に使用されているインデックスを確認できる優れたツールがいくつか用意されています。この記事 ( http://www.mssqltips.com/tip.asp?tip=1239 ) では、インデックスがどれだけ更新されているかではなく、どれだけ使用されているかをよりよく理解できるクエリをいくつか紹介しています。

于 2010-02-16T17:59:45.500 に答える
0

これは、Where句で使用されている列に完全に基づいています。また、経験則として、デッドロックを回避するために外部キー列にインデックスを付ける必要があります。AWRレポートは、インデックスの必要性を理解するために定期的に分析する必要があります。

于 2010-09-26T12:27:00.160 に答える