web-dev-qa-db-ja.com

非正規化はデータベースのパフォーマンスをどのように改善しますか?

特定のアプリケーションのパフォーマンスを改善するために行われた非正規化について多くのことを聞きました。しかし、私は関連することをしようとしたことはありません。

だから、私は好奇心が強いです、正規化されたDBのどこがパフォーマンスを悪化させるのですか、言い換えれば、非正規化の原則は何ですか?

パフォーマンスを改善する必要がある場合、この手法を使用するにはどうすればよいですか?

58
Roman

非正規化は時間空間トレードオフです。正規化されたデータは必要なスペースが少なくなりますが、必要な結果セットを作成するために結合が必要になる場合があり、それにより時間がかかります。非正規化されている場合、データは複数の場所で複製されます。その後、より多くのスペースが必要になりますが、データの目的のビューはすぐに利用できます。

次のような他の時空間最適化があります

  • 非正規化ビュー
  • 事前計算された列

そのようなアプローチのいずれかと同様に、これはデータの読み取り(容易に利用できるため)を改善しますが、データの更新はより高価になります(複製または事前計算されたデータを更新する必要があるため) )。

70
ewernli

非正規化は通常、次のいずれかに使用されます。

  • 特定の数のクエリを避ける
  • いくつかの結合を削除する

非正規化の基本的な考え方は、冗長データを追加するか、いくつかをグループ化して、それらのデータをより簡単に、より少ないコストで取得できるようにすることです。これはパフォーマンスに優れています。


簡単な例?

  • ブログの「投稿」と「コメント」の表を考えてみてください。
    • 各投稿について、「コメント」テーブルに複数の行があります。
    • これは、コメントの数が関連付けられた投稿のリストを表示するには、次のことを行う必要があることを意味します。
      • 1つのクエリを実行して投稿を一覧表示する
      • 投稿ごとに1つのクエリを実行して、コメントの数をカウントします(はい、それらを1つにマージして、一度にすべての投稿の数を取得できます)
      • これはいくつかのクエリを意味します。
  • ここで、「コメント数」フィールドを投稿テーブルに追加すると:
    • 投稿を一覧表示するために必要なクエリは1つだけです
    • また、Commentsテーブルを照会する必要はありません。コメントの数は、Postsテーブルに対して既に非正規化されています。
    • また、1つ以上のフィールドを返すクエリは、複数のクエリよりも優れています。

今、いくつかのコストがあります、はい:

  • まず、いくつかの冗長な情報があるため、これにはディスクとメモリの両方でいくらかの場所が必要です:
    • コメントの数は投稿テーブルに保存されます
    • また、コメント表でそれらの数を数えることもできます
  • 次に、誰かがコメントを追加/削除するたびに、次のことを行う必要があります。
    • もちろん、コメントを保存/削除します
    • ただし、Postsテーブルの対応する番号も更新します。
    • しかし、ブログにコメントを書くよりも多くの人が読んでいる場合、これはおそらくそれほど悪くないでしょう。
84
Pascal MARTIN

「非正規化」という言葉は、設計上の問題の混乱を招きます。非正規化によって高性能データベースを取得しようとすることは、ニューヨークから離れて目的地に到達しようとするようなものです。どちらに行くべきかはわかりません。

必要なのは、その設計が正規化の規則と矛盾する場合でも、シンプルで健全な設計を生み出す優れた設計規律です。

そのような設計規律の1つはスタースキーマです。スタースキーマでは、単一のファクトテーブルがテーブルのスターのハブとして機能します。他のテーブルはディメンションテーブルと呼ばれ、スキーマの端にあります。ディメンションは、車輪のスポークのように見える関係によってファクトテーブルに接続されます。スタースキーマは基本的に、多次元設計をSQL実装に投影する方法です。

スタースキーマに密接に関連しているのはスノーフレークスキーマで、これはもう少し複雑です。

優れたスタースキーマがあれば、2つのディメンションと1つのファクトテーブルを含む、3方向結合のみでデータのさまざまな組み合わせを取得できます。それだけでなく、多くのOLAPツールは、星のデザインを自動的に解読し、さらにプログラミングすることなく、ポイントアンドクリック、ドリルダウン、データへのグラフィカル分析アクセスを可能にします。 。

スタースキーマデザインは、2番目と3番目の標準形式に違反することがありますが、レポートと抽出の速度と柔軟性が向上します。ほとんどの場合、データウェアハウス、データマート、およびレポートデータベースで使用されます。一般に、スタースキーマやその他の検索指向のデザインからは、偶然の「非正規化」よりもはるかに優れた結果が得られます。

11
Walter Mitty

非正規化の重要な問題は次のとおりです。

  • 複製するデータとその理由の決定
  • データを同期させる方法の計画
  • 非正規化フィールドを使用するようにクエリをリファクタリングします。

非正規化の最も簡単なタイプの1つは、結合を回避するためにIDフィールドをテーブルに入力することです。アイデンティティは決して変更されるべきではないので、これはデータの同期を保つ問題がめったに起こらないことを意味します。たとえば、クライアントIDをいくつかのテーブルに設定します。これは、クライアントごとにクエリする必要があることが多く、クエリでは、クライアントテーブルとクエリ対象のテーブルの間にあるテーブルのデータが必ずしも必要ではないためですデータが完全に正規化された場合。クライアント名を取得するには1回の結合を行う必要がありますが、クエリしているテーブルの外から必要なデータがそれだけである場合、6つの親テーブルに結合してクライアント名を取得するよりも優れています。

ただし、介在するテーブルのデータが必要なクエリを頻繁に実行しない限り、これにはメリットはありません。

別の一般的な非正規化は、名前フィールドを他のテーブルに追加することです。名前は本質的に変更可能であるため、名前がトリガーと同期していることを確認する必要があります。ただし、これにより2ではなく5つのテーブルに結合する必要がなくなった場合は、挿入または更新が少し長くなるだけのコストに見合う価値があります。

7
HLGEM

レポートなどの特定の要件がある場合、さまざまな方法でデータベースを非正規化することができます。

  • 特定のデータ複製を導入して、いくつかのJOINを節約します(たとえば、特定の情報をテーブルに入力し、複製されたデータで大丈夫です。そのため、そのテーブル内のすべてのデータは、別のテーブルを結合して見つける必要はありません)

  • 特定の値を事前に計算してテーブルの列に保存し、データベースを照会するたびにその場でそれらを計算することができます。もちろん、これらの計算値は時間の経過とともに「古くなる」可能性があり、ある時点で再計算する必要がありますが、通常、固定値を読み取るだけで何かを計算するよりも安価です(子行をカウントするなど)

もちろん、データベーススキーマを非正規化してパフォーマンスを向上させる方法は他にもありますが、そうすることである程度のトラブルに巻き込まれることに注意する必要があります。これらの決定を下す際には、長所と短所(パフォーマンス上の利点と自分が直面する問題)を慎重に比較検討する必要があります。

3
marc_s

適切に正規化された親子関係を持つデータベースを検討してください。

カーディナリティが平均2x1であるとしましょう。

p行の2つのテーブルParentがあります。 2x p行の子。

結合操作は、p親行、2x p子行を読み取る必要があることを意味します。読み取られる行の総数はp + 2x pです。

これを子行2x pのみの単一のテーブルに非正規化することを検討してください。読み込まれる行の数は2x pです。

行数が少ない==物理I/Oが少ない==高速。

1
S.Lott

この記事の最後のセクションでは、

https://technet.Microsoft.com/en-us/library/aa224786%28v=sql.80%29.aspx

virtual Denormalizationを使用すると、より単純なSQLクエリをより高速に実行するために非正規化データを使用してビューを作成できますが、基になるテーブルはより高速な追加/更新操作のために正規化されたままになります(むしろ、定期的にリアルタイムよりも)。私は自分でリレーショナルデータベースのクラスを取っているだけですが、私が読んでいるものから、このアプローチは私にとって理にかなっているようです。

0
RJCurrie