私はデータベースを正規化する慣行に固執しようとしていますが、それは複数の結合クエリを実行する必要につながります. 多くのクエリが結合を使用する場合と、冗長データを含む可能性のある単一のテーブルを呼び出す場合、パフォーマンスが低下しますか?
7 に答える
ボトルネックが発見されるまで、データベースを正規化しておいてください。その後、慎重にプロファイリングした後にのみ、非正規化する必要があります。
ほとんどの場合、インデックスの適切なカバー セットと最新の統計情報があれば、非正規化を行わなくても、ほとんどのパフォーマンスとブロッキングの問題を解決できます。
単一のテーブルを使用すると、テーブルに対する読み取りだけでなく書き込みもある場合、パフォーマンスが低下する可能性があります。
マイケル・ジャクソン(その一人ではない)が言ったと信じられていることは有名です。
- プログラム最適化の第 1 のルール: やらないこと。
- プログラム最適化の第 2 のルール – 専門家のみ: まだ実行しないでください。
それはおそらく RDBMS が登場する前のことですが、RDBMS を含めるようにルールを拡張したと思います。
正規化されたデータ モデルでは、ほとんどの場合、複数テーブルの SELECT が必要です。この種の質問でよくあることですが、「非正規化」に対する「正しい」答えは? 質問はいくつかの要因に依存します。
DBMS プラットフォーム。
複数テーブル クエリと単一テーブル クエリの相対的なパフォーマンスは、アプリケーションが存在するプラットフォームの影響を受けます。クエリ オプティマイザーの高度なレベルはさまざまです。たとえば、私の経験では、MySQL は単一テーブルのクエリでは非常に高速ですが、複数の結合を含むクエリはそれほど最適化されません。これは、小さなテーブル (たとえば 10K 行未満) では実際の問題ではありませんが、大きなテーブル (10M 以上) では実際に問題になります。
データ量
100K 以上の行領域のテーブルを見ている場合を除き、ほとんど問題はありません。数百行のテーブル サイズを見ている場合は、インデックス作成について考える必要さえありません。
(非)正規化
正規化の要点は、重複を最小限に抑え、更新が必要なフィールド値を 1 か所だけ変更する必要があることを確認することです。非正規化はそれを破りますが、複製されたデータへの更新がめったにない場合 (理想的には発生しないはずです)、それほど問題にはなりません。したがって、最も静的なデータ以外を複製する前に、非常に慎重に検討してください。データベースが大幅に拡大する可能性があることに注意してください。
要件/制約
満たそうとするパフォーマンス要件は何ですか? 固定ハードウェアまたは予算はありますか? パフォーマンスの向上は、ハードウェアのアップグレードによって最も簡単に、そして最も安価に実現できる場合があります。どのくらいの取引量を期待していますか? 中小企業の会計システムは、たとえば Twitter とは非常に異なるプロファイルを持っています。
最後に 1 つの考えが浮かびます: 十分に非正規化すると、データベースはフラット ファイルとどう違うのでしょうか? SQL は、柔軟なデータと多次元の取得には優れていますが、単純なシーケンシャル ファイルやかなり単純なインデックス ファイルよりも (少なくとも) 桁違いに遅くなる可能性があります。
性能差?
正気の違い。
正規化のためにテーブルを分解するにはコストがかかります。そのコストにはパフォーマンス コンポーネントがあります。テーブルの分解とクエリでのデータの結合のパフォーマンス コストは、次の方法で低く抑えることができます。優れた DBMS を使用する。テーブルを正しく設計する。インデックスを正しく設計する。オプティマイザーに仕事をさせます。物理設計の DBMS 固有の機能を調整します。
結合を具体化する大きなテーブルを構成するコストもあります。更新の異常とプログラミングの難しさに関するコストは、正規化に関する優れたチュートリアルで概説されています。また、テーブルを構成するためのパフォーマンス コストもあります。多くの DBMS 製品では、非常に大きな行をメモリにロードすると、小さな行をロードするよりもコストがかかります。非常に幅の広いテーブルを作成すると、DBMS に非常に大きな行を読み込ませることになり、メモリに読み込まれたほとんどのデータを破棄するだけになります。これにより、正規化よりもさらに遅くなる可能性があります。
一般に、ランダムに非正規化しないでください。必要に応じて、たとえその規律が何らかの非正規化をもたらしたとしても、あなたの前に行った人々によってテストされた設計規律を使用してください。そのような分野としてスタースキーマをお勧めします。それには多くのことが必要です。また、正規化された設計がスター スキーマ設計よりもうまく機能する状況はまだたくさんあります。
複数の設計原則のセットを学習し、どのセットをいつ使用するかを学習することは、専門家になるための学習の第 2 段階です。
コードの最適化をコンパイラに任せるのと同じ理由で、クエリの最適化をデータベースに任せます。
最近のほとんどの RDBMS は、この点で非常に優れています。
場合によっては非正規化が「問題ない」と考える前に、次のことを考慮してください。通常、すべての属性に関心があるわけではありません。したがって、不要なデータをディスクからロードすることは非効率的です (通常、データベースの最も効率の悪いコンポーネントです)。これは、多数の冗長データが連続する非正規化された設計の場合、さらに悪化する可能性があります。その冗長データをすべて更新する必要がある場合は、さらに悪化します。対象の列のみを含むいくつかの狭いテーブルをロードして結合する方がはるかに効率的です。繰り返しますが、これはデータベースに依存するため、プロファイリングを行わないと手掛かりがありません。
パフォーマンスについて本当に心配している場合は、おそらくスケーラビリティの問題について話しているでしょう。この場合、適切な (正規化された) スキーマ設計が重要なshardingを検討することをお勧めします。
適切なインデックスを設定すると、結合を非常に迅速に実行できます。SQL プロファイラーを使用して、一般的なクエリのパフォーマンスを最適化するために作成または変更する必要があるインデックスを特定します。統計とインデックスを更新するデータベースを週に 1 回 (または頻繁に変更されるテーブルの場合は毎日) 実行するように、メンテナンス プランを設定してください。
通常、複数の場所にデータを保持するよりも、正規化が優先されます。挿入/更新を迅速に行う必要がなく、選択を非常に迅速に行う必要があるシナリオがあります。この場合、正規化を行わないほうがよい場合があります。それでも、時期尚早の最適化は推奨されないため、最初に正規化された構造を使用してください。
実際、一部のクラウド サイトで利用できる究極の超最適化の 1 つは、効率を高めるために、少数のより広範で限られた機能のテーブルを使用することです。これまでのところ、大規模なスケーリングが必要な場合は、これが 1 つの方法です。しかし、それはリレーショナル dbms (そうではない) にとって望ましいプラクティスとは見なされません。
パフォーマンスに問題がある場合は、何らかの非正規化を行う前に、最初に取り組むべきことがたくさんあります。