web-dev-qa-db-ja.com

データベースインデックスを追加するのは時期尚早の最適化ですか?

今日の私の同僚は、アプリケーション内のすべてのクエリを調べ、それに応じてインデックスを追加することを提案しました。

アプリケーションがまだリリースされていないため、これは時期尚早の最適化だと思います。ライブになったら遅いクエリを監視し、それに応じてインデックスを追加することを提案しました。

データベースを設計するときの一般的な合意は何ですか?新しいクエリを作成するたびに一致するインデックスを追加する必要がありますか?それとも、単に監視してそれがどうなるかを見る方が良いですか?

61
Marco de Jongh

早すぎる最適化とは何かを「最適化」することです。なぜなら、これはおそらく遅くなるという漠然とした直感的な感覚によるものです特にコードの可読性と保守性の低下に対して。これは、パフォーマンスに関して確立された優れた慣行に故意に従わないことを意味するものではありません。

時々それを描くのは難しいですが、実際に稼働する前にインデックスを追加しないことは間違いなく遅すぎる最適化;と言います。これにより、アーリーアダプター(最も熱心で最も重要なユーザー)が罰せられ、製品に対する否定的な見方が与えられ、レビューやディスカッションなどに広がります。インデックス作成が必要な問題を見つけるためのクエリの監視は、良い考えですが、ベータ版までにそれを行うようにしてください。

132
Mason Wheeler

ライブになったら遅いクエリを監視する

デザインの欠如でユーザーを苦しめるほどの品質はありません!

テーブルを設計するとき、どのクエリがインデックスを必要とするか、where句と結合でどの列がクエリされるかを知っている必要があります。格納されている負荷またはデータが増加すると、ライブ環境では明らかにならない可能性のあることがすぐに明らかになる可能性があるため、これらにはすでにインデックスを付けておく必要があります。これが発生したときに実行したくないのは、すべての「遅い」クエリでインデックスをスラップすることです。すべてのインデックスが作成されます。

48
gbjbaanb

「時期尚早の最適化」とは、中傷的な意味で、必要のないコストのかかる最適化を意味します。それはしない破産を防ぐために可能な限り最新の時点の前に実装されたすべての最適化を意味します!

特に、実際に稼働する前に、パフォーマンステストに基づいて最適化し、アプリが完全に機能しないための賢明な(概算ではありますが)要件を確実に満たすことは正当です。

最低限妥当な量のテストデータをデータベースにロードし、アプリの応答性を確認する必要があります。これが起こることはわかっているので、これは時期尚早ではなく、非常に遅いスキャンをトリガーするクエリをキャッチします。 A Eがコメントで言うように:

インデックスを使用して、エンドユーザーが通常リアルタイムで行うクエリの全テーブルスキャンを回避します。

少なくとも、使用が増える予定のテーブルの場合。

次に、そのショートカットとして、データベースエンジンの経験が豊富で、コードの最初のカットを作成するときにすでにテストを計画している場合、実行していなくてもクエリを実行していることがわかります。インデックスがないと書き込みが遅くなります。もちろん、あなたが知らないふりをして、インデックスを追加する前にテストが失敗するのを見て自由にできますが、既知の障害のあるコード(応答しないため)が稼働する理由はありません。

26
Steve Jessop

アプリケーションがまだリリースされていないため、これは時期尚早の最適化だと思います。ライブになったら遅いクエリを監視し、それに応じてインデックスを追加することを提案しました。

エンドユーザーや本番環境を品質保証のように扱うことはできません。より多くの言葉で、あなたはあなたが生産でそれを理解するだろうと言っています。私はそれが正しい方法だとは思いません、そして私はそのアプローチが毎日ひどく間違っていることを知っています

幅の広いブラシでこれをペイントすることはできないため、1つの点に注意する必要があります。

あなたは何ですか 一般的な作業負荷

それは明白または退屈に聞こえるかもしれませんが、実際には重要です。ワークロードの98%を占める10個のクエリがある場合(かなり一般的ですが、信じられないかもしれませんが)、私の推奨は製造前のハード分析。現実的で代表的なデータを使用して、これらの10個のクエリが可能な限り優れていることを確認してください(perfectは貴重な時間の無駄であり、ほとんど達成できません)。

ワークロードの2%を構成する他の200のクエリの場合、これらは、おそらく大量の作業に値しないものであり、本番環境での奇妙な問題をトラブルシューティングする、特殊なケースのパフォーマンスを構成します。それも現実であり、ひどく悪いことではありません。ただし、これは、インデックス作成のベストプラクティスを無視したり、データの取得について推定を行うことを意味するものではありません。

運用前にデータベースのパフォーマンスを把握することは一般的であり、優れた方法です。実際、このタイプのことには 開発DBA と呼ばれる比較的一般的な立場があります。

だが...

一部の人はそれをやりすぎて、「念のため」インデックスを追加することに夢中になります。誰かがこれが欠落しているインデックスであることを推奨していますか?それと、他の4つのバリエーションを追加します。また悪い考えです。データの取得だけでなく、データの変更についても考える必要がありますか?テーブルのインデックスが多いほど、一般に、データを変更するときにオーバーヘッドが大きくなります。

ほとんどのものと同様に、健康的なバランスがあります。

おもしろいちょっとした付記として...「インデックス」の複数形化

「インデックス」は金融関係者向けです

「インデックス」は私たちのものです

20
Thomas Stringer

いいえ、これは時期尚早の最適化ではありませんが、他の最適化と同様に正しく実行する必要があります。

これが私がすることです:

  1. 本番負荷を模倣するのに十分なテストデータをデータベースにロードします。これを100%正確にすることはできませんが、それで十分です。十分なデータを入れてください。1つのテーブルに固定量のデータがありますか?それをロードします。たとえば、多くのデータを保持する1つのテーブルがありますか?このサイトで質問があるテーブルは何ですか?たとえダミーデータであっても、数百万のレコードを読み込みます。
  2. プロファイリングを有効にするデータベースサーバーで。
  3. 自動化されたスクリプト(ボリュームを提供します)と実際のユーザー(物事を壊す方法を知っている)の組み合わせを使用して、アプリケーションを操作します。
  4. プロファイリングデータを確認します。特定のクエリは遅いですか? EXPLAIN PLANを確認し、データベースサーバーからインデックスがwantsと通知されているが、それが存在しないかどうかを確認してください。

データベースサーバーは、複雑でインテリジェントなソフトウェアです。聞く方法を知っていれば、最適化の方法を教えてくれます。

重要なのは測定最適化の前後のパフォーマンス、そしてデータベースに必要なものを通知させるです。

4
user22815

既知の問題(IDによるレコードの検索など)の実証済みのパターンに従うことは、時期尚早ではありません。それは賢明です。

とはいえ、インデックスは必ずしも単純なビジネスとは限りません。トラフィックがどのインデックスに依存し、どれが書き込み操作のボトルネックになるかを設計段階で知ることはしばしば困難です。したがって、「明白な」スキーマ設計のベストプラクティスを活用することを主張します(設計された読み取り/書き込みパターンとインデックスFKに適したPKを使用してください)。ただし、ストレステストで必要になるまで、他のインデックスを作成しないでください。

3
svidgen

アプリケーションがリリースされたとき、それは遅すぎます。

ただし、適切な開発プロセスには、パフォーマンステストを含める必要があります。

パフォーマンステストの結果を使用して、追加するインデックスを決定し、パフォーマンステストを繰り返してその効果を確認します。

2
Philipp

すべてのクエリを最適化する必要があるとは思いませんが、インデックスはRDBMSの一部なので、リリースする前に考慮する必要があります。クエリを実行するとき、他の形式のプログラミングとは異なり、クエリの実行方法をシステムに伝えません。彼らは独自の計画を立て、ほとんどの場合、それはインデックスの可用性に基づいています。データの構成と量も後で検討されます。

ここに私が検討するいくつかの事柄があります:

  1. 頻繁に使用されることがわかっている、開発の初期段階で特定する必要のあるクエリがいくつかあります。それらに焦点を当てます。
  2. クエリが遅くなります。最初にインデックスを作成することで、パフォーマンスがまだ十分でないかどうかを判断し、再設計を検討できます(非正規化は時期尚早かもしれません)。私はリリース前にこれをしたいです。誰もが在庫から何かを見つけるのに10分かかるシステムを望んでいません。
  3. インデックスはクエリのパフォーマンスを向上させますが、データの変更を妨げるものではありません。
  4. 多くのシステムにはクエリを分析するためのツールがあるので、それらを使用することを恐れないでください。

最初のレビューの後、これを再度レビューするタイミングと、これを行うために情報を収集する方法(使用状況の監視、クライアントデータのコピーの取得など)に関するいくつかの考慮事項をフォローアップする必要があります。

時期尚早に最適化したくないと思いますが、データベースのインデックスを作成しないとパフォーマンスが低下することはほぼ確実です。これを邪魔にならないようにすることで、パフォーマンスの問題を引き起こしている他の領域があるかどうかを判断できます。

1
JeffO

事前の分析によって、どの列が確実にインデックスを必要とするかを特定することをお勧めします。インデックスがまったくない場合、データベースのサイズが大きくなるため、本番環境では段階的または予期しないパフォーマンス低下のリスクがあります。避けたい状況は、一般的に実行されるクエリで多数のテーブル行をスキャンする必要がある場合です。重要な列にインデックスを追加することは時期尚早の最適化ではありません。必要な情報の多くが利用可能であり、潜在的なパフォーマンスの違いが大きいためです(桁違い)。インデックスの利点があまり明確でないか、データに依存している状況もあります。これらのケースのいくつかについては、おそらく決定を延期することができます。

あなたが尋ねる必要があるいくつかの質問は次のとおりです:

  • 各テーブルのサイズの設計上の制限はどのようになりますか?

テーブルが常に小さくなる(たとえば100行未満)場合、データベースがテーブル全体をスキャンする必要があっても、問題はありません。インデックスを追加することは有益かもしれませんが、これは決定するためにもう少し専門知識または測定を必要とします。

  • 各クエリが実行される頻度と、必要な応答時間はどれくらいですか?

クエリが頻繁に実行されず、厳密な応答時間要件(レポートの生成など)がなく、行数がそれほど多くない場合は、インデックスの追加を延期することはおそらく安全です。繰り返しますが、専門知識や測定は、それが有益になるかどうかを判断するのに役立ちます。

  • クエリでは、主キー以外の方法でテーブルを検索する必要がありますか?例えば。日付範囲によるフィルタリング、外部キーの結合?

これらのクエリが頻繁に実行され、行数の多いテーブルに触れる場合は、事前にインデックスを追加することを真剣に検討する必要があります。これがクエリに当てはまるかどうかわからない場合は、データベースに現実的な量のデータを入力してから、クエリプランを確認できます。

0
user611910

また、予想されるユーザー数にも依存します。負荷テストを確実に行い、データベースが数十から数百から数千の同時リクエストに対応できることを確認してください。繰り返しますが、それは予想されるトラフィックの量と、他の領域よりも多く使用されると予想される領域によって異なります。

一般的に、ユーザーが最初にヒットすると予想される領域を微調整します。次に、ユーザーエクスペリエンスの観点から遅いものを微調整します。ユーザーが何かを待たなければならないときはいつでも、彼らは悪い経験をして、断られるかもしれません。良くない!

0
harsimranb