今日の私の同僚は、アプリケーション内のすべてのクエリを調べ、それに応じてインデックスを追加することを提案しました。
アプリケーションがまだリリースされていないため、これは時期尚早の最適化だと思います。ライブになったら遅いクエリを監視し、それに応じてインデックスを追加することを提案しました。
データベースを設計するときの一般的な合意は何ですか?新しいクエリを作成するたびに一致するインデックスを追加する必要がありますか?それとも、単に監視してそれがどうなるかを見る方が良いですか?
早すぎる最適化とは何かを「最適化」することです。なぜなら、これはおそらく遅くなるという漠然とした直感的な感覚によるものです特にコードの可読性と保守性の低下に対して。これは、パフォーマンスに関して確立された優れた慣行に故意に従わないことを意味するものではありません。
時々それを描くのは難しいですが、実際に稼働する前にインデックスを追加しないことは間違いなく遅すぎる最適化;と言います。これにより、アーリーアダプター(最も熱心で最も重要なユーザー)が罰せられ、製品に対する否定的な見方が与えられ、レビューやディスカッションなどに広がります。インデックス作成が必要な問題を見つけるためのクエリの監視は、良い考えですが、ベータ版までにそれを行うようにしてください。
ライブになったら遅いクエリを監視する
デザインの欠如でユーザーを苦しめるほどの品質はありません!
テーブルを設計するとき、どのクエリがインデックスを必要とするか、where句と結合でどの列がクエリされるかを知っている必要があります。格納されている負荷またはデータが増加すると、ライブ環境では明らかにならない可能性のあることがすぐに明らかになる可能性があるため、これらにはすでにインデックスを付けておく必要があります。これが発生したときに実行したくないのは、すべての「遅い」クエリでインデックスをスラップすることです。すべてのインデックスが作成されます。
「時期尚早の最適化」とは、中傷的な意味で、必要のないコストのかかる最適化を意味します。それはしない破産を防ぐために可能な限り最新の時点の前に実装されたすべての最適化を意味します!
特に、実際に稼働する前に、パフォーマンステストに基づいて最適化し、アプリが完全に機能しないための賢明な(概算ではありますが)要件を確実に満たすことは正当です。
最低限妥当な量のテストデータをデータベースにロードし、アプリの応答性を確認する必要があります。これが起こることはわかっているので、これは時期尚早ではなく、非常に遅いスキャンをトリガーするクエリをキャッチします。 A Eがコメントで言うように:
インデックスを使用して、エンドユーザーが通常リアルタイムで行うクエリの全テーブルスキャンを回避します。
少なくとも、使用が増える予定のテーブルの場合。
次に、そのショートカットとして、データベースエンジンの経験が豊富で、コードの最初のカットを作成するときにすでにテストを計画している場合、実行していなくてもクエリを実行していることがわかります。インデックスがないと書き込みが遅くなります。もちろん、あなたが知らないふりをして、インデックスを追加する前にテストが失敗するのを見て自由にできますが、既知の障害のあるコード(応答しないため)が稼働する理由はありません。
アプリケーションがまだリリースされていないため、これは時期尚早の最適化だと思います。ライブになったら遅いクエリを監視し、それに応じてインデックスを追加することを提案しました。
エンドユーザーや本番環境を品質保証のように扱うことはできません。より多くの言葉で、あなたはあなたが生産でそれを理解するだろうと言っています。私はそれが正しい方法だとは思いません、そして私はそのアプローチが毎日ひどく間違っていることを知っています 。
幅の広いブラシでこれをペイントすることはできないため、1つの点に注意する必要があります。
それは明白または退屈に聞こえるかもしれませんが、実際には重要です。ワークロードの98%を占める10個のクエリがある場合(かなり一般的ですが、信じられないかもしれませんが)、私の推奨は製造前のハード分析。現実的で代表的なデータを使用して、これらの10個のクエリが可能な限り優れていることを確認してください(perfectは貴重な時間の無駄であり、ほとんど達成できません)。
ワークロードの2%を構成する他の200のクエリの場合、これらは、おそらく大量の作業に値しないものであり、本番環境での奇妙な問題をトラブルシューティングする、特殊なケースのパフォーマンスを構成します。それも現実であり、ひどく悪いことではありません。ただし、これは、インデックス作成のベストプラクティスを無視したり、データの取得について推定を行うことを意味するものではありません。
運用前にデータベースのパフォーマンスを把握することは一般的であり、優れた方法です。実際、このタイプのことには 開発DBA と呼ばれる比較的一般的な立場があります。
一部の人はそれをやりすぎて、「念のため」インデックスを追加することに夢中になります。誰かがこれが欠落しているインデックスであることを推奨していますか?それと、他の4つのバリエーションを追加します。また悪い考えです。データの取得だけでなく、データの変更についても考える必要がありますか?テーブルのインデックスが多いほど、一般に、データを変更するときにオーバーヘッドが大きくなります。
ほとんどのものと同様に、健康的なバランスがあります。
おもしろいちょっとした付記として...「インデックス」の複数形化
「インデックス」は金融関係者向けです
「インデックス」は私たちのものです
いいえ、これは時期尚早の最適化ではありませんが、他の最適化と同様に正しく実行する必要があります。
これが私がすることです:
データベースサーバーは、複雑でインテリジェントなソフトウェアです。聞く方法を知っていれば、最適化の方法を教えてくれます。
重要なのは測定最適化の前後のパフォーマンス、そしてデータベースに必要なものを通知させるです。
既知の問題(IDによるレコードの検索など)の実証済みのパターンに従うことは、時期尚早ではありません。それは賢明です。
とはいえ、インデックスは必ずしも単純なビジネスとは限りません。トラフィックがどのインデックスに依存し、どれが書き込み操作のボトルネックになるかを設計段階で知ることはしばしば困難です。したがって、「明白な」スキーマ設計のベストプラクティスを活用することを主張します(設計された読み取り/書き込みパターンとインデックスFKに適したPKを使用してください)。ただし、ストレステストで必要になるまで、他のインデックスを作成しないでください。
アプリケーションがリリースされたとき、それは遅すぎます。
ただし、適切な開発プロセスには、パフォーマンステストを含める必要があります。
パフォーマンステストの結果を使用して、追加するインデックスを決定し、パフォーマンステストを繰り返してその効果を確認します。
すべてのクエリを最適化する必要があるとは思いませんが、インデックスはRDBMSの一部なので、リリースする前に考慮する必要があります。クエリを実行するとき、他の形式のプログラミングとは異なり、クエリの実行方法をシステムに伝えません。彼らは独自の計画を立て、ほとんどの場合、それはインデックスの可用性に基づいています。データの構成と量も後で検討されます。
ここに私が検討するいくつかの事柄があります:
最初のレビューの後、これを再度レビューするタイミングと、これを行うために情報を収集する方法(使用状況の監視、クライアントデータのコピーの取得など)に関するいくつかの考慮事項をフォローアップする必要があります。
時期尚早に最適化したくないと思いますが、データベースのインデックスを作成しないとパフォーマンスが低下することはほぼ確実です。これを邪魔にならないようにすることで、パフォーマンスの問題を引き起こしている他の領域があるかどうかを判断できます。
事前の分析によって、どの列が確実にインデックスを必要とするかを特定することをお勧めします。インデックスがまったくない場合、データベースのサイズが大きくなるため、本番環境では段階的または予期しないパフォーマンス低下のリスクがあります。避けたい状況は、一般的に実行されるクエリで多数のテーブル行をスキャンする必要がある場合です。重要な列にインデックスを追加することは時期尚早の最適化ではありません。必要な情報の多くが利用可能であり、潜在的なパフォーマンスの違いが大きいためです(桁違い)。インデックスの利点があまり明確でないか、データに依存している状況もあります。これらのケースのいくつかについては、おそらく決定を延期することができます。
あなたが尋ねる必要があるいくつかの質問は次のとおりです:
テーブルが常に小さくなる(たとえば100行未満)場合、データベースがテーブル全体をスキャンする必要があっても、問題はありません。インデックスを追加することは有益かもしれませんが、これは決定するためにもう少し専門知識または測定を必要とします。
クエリが頻繁に実行されず、厳密な応答時間要件(レポートの生成など)がなく、行数がそれほど多くない場合は、インデックスの追加を延期することはおそらく安全です。繰り返しますが、専門知識や測定は、それが有益になるかどうかを判断するのに役立ちます。
これらのクエリが頻繁に実行され、行数の多いテーブルに触れる場合は、事前にインデックスを追加することを真剣に検討する必要があります。これがクエリに当てはまるかどうかわからない場合は、データベースに現実的な量のデータを入力してから、クエリプランを確認できます。
また、予想されるユーザー数にも依存します。負荷テストを確実に行い、データベースが数十から数百から数千の同時リクエストに対応できることを確認してください。繰り返しますが、それは予想されるトラフィックの量と、他の領域よりも多く使用されると予想される領域によって異なります。
一般的に、ユーザーが最初にヒットすると予想される領域を微調整します。次に、ユーザーエクスペリエンスの観点から遅いものを微調整します。ユーザーが何かを待たなければならないときはいつでも、彼らは悪い経験をして、断られるかもしれません。良くない!