パフォーマンスを改善するために非正規化しますか?説得力がありますが、水を保持しません。
テッドコッド博士と協力してリレーショナルデータモデルの最初の支持者であったクリスデイは、正規化に対する誤った情報に基づく議論に我慢できず、科学的手法を使用して体系的に破壊しました:彼は大規模なデータベースを取得し、これらの主張をテストしました。
私は彼がそれを書いたと思うのリレーショナル・データベース・著作1988年から1991年が、この本は、後の版6に圧延したデータベースシステムに導入され、私が書くと可能性を維持するように、データベースの理論と設計上の決定的なテキストは第8版では、今後数十年間印刷されます。私たちのほとんどがまだ裸足で走り回っていたとき、クリス・デートはこの分野の専門家でした。
彼はそれを発見しました:
- それらのいくつかは特別なケースを保持します
- それらのすべては一般的な使用のために報われることに失敗します
- それらすべては他の特別な場合には著しく悪い
それはすべて、ワーキングセットのサイズを軽減することに戻ります。適切に選択されたキーと適切に設定されたインデックスを含む結合は、ローがマテリアライズされる前に結果を大幅にプルーニングできるため、安価で高価ではありません。
結果の具体化には、大量のディスクの読み取りが含まれます。これは、1桁の規模で最も費用のかかる作業です。対照的に、結合を実行するには、論理的にはキーのみの取得が必要です。実際には、キー値さえフェッチされません。キーハッシュ値は結合の比較に使用され、複数列の結合のコストを軽減し、文字列の比較を伴う結合のコストを大幅に削減します。キャッシュの適合性が大幅に向上するだけでなく、実行するディスクの読み取りが大幅に少なくなります。
さらに、優れたオプティマイザは、最も制限の多い条件を選択し、それを結合を実行する前に適用します。これにより、カーディナリティの高いインデックスでの結合の高い選択性が非常に効果的に活用されます。
確かに、この種の最適化は非正規化データベースにも適用できますが、スキーマを非正規化したい人は、通常、インデックスを設定するとき(ある場合)のカーディナリティについては考えません。
テーブルスキャン(結合を作成する過程でのテーブル内のすべての行の検査)は実際にはまれであることを理解することが重要です。クエリオプティマイザーは、次の1つ以上が成立する場合にのみテーブルスキャンを選択します。
- リレーションの行数が200未満です(この場合、スキャンのほうが安くなります)
- 結合列に適切なインデックスがありません(これらの列で結合することが意味がある場合、なぜインデックス付けされないのですか?修正してください)
- 列を比較する前に型強制が必要です(WTF ?!修正するか、帰宅します)ADO.NETの問題に関するエンドノートを参照してください
- 比較の引数の1つは式(インデックスなし)です
操作を実行することは、実行しないことよりもコストがかかります。ただし、誤った操作を実行し、無意味なディスクI / Oを強制し、本当に必要な結合を実行する前にドロスを破棄すると、はるかにコストがかかります。「間違った」操作が事前に計算され、インデックスが適切に適用されている場合でも、重大なペナルティが残ります。結合を事前計算するための非正規化は、更新の異常が伴うにもかかわらず、特定の結合への取り組みです。あなたが必要な場合は異なるが参加し、そのコミットメントは、あなたがコストに起こっている大。
世界が変わりつつあることを誰かに思い出させたいのであれば、グランティアハードウェア上のより大きなデータセットは、Dateの調査結果の広がりを誇張しているだけだと思います。
課金システムまたはジャンクメールジェネレーター(あなたに恥)に取り組んでいて、非正規化の方が速いという申し訳ありませんが、特別なものの1つに住んでいますケース-具体的には、すべてのデータを順番に処理するケース。これは、一般的なケースではありません、あなたがしているあなたの戦略に正当化。
あなたはされていない誤って、それを一般化して正当化。データウェアハウジングシナリオでの非正規化の適切な使用の詳細については、「メモ」セクションの最後を参照してください。
私も対応したいと思います
結合は、リップグロスを含む単なるデカルト製品です
なんと大量のボロック。制限はできるだけ早く適用され、最も制限が最初に適用されます。あなたは理論を読みましたが、あなたはそれを理解していません。結合は、クエリオプティマイザによってのみ「述語が適用されるデカルト積」として扱われます。これはシンボリック表現(実際は正規化)であり、シンボリック分解を容易にするため、オプティマイザは同等の変換をすべて生成し、コストと選択性によってランク付けして、最適なクエリプランを選択できます。
オプティマイザにデカルト積を生成させる唯一の方法は、述語を提供しないことです。 SELECT * FROM A,B
ノート
David Aldridgeがいくつかの重要な追加情報を提供します。
実際、インデックスとテーブルスキャン以外にもさまざまな戦略があり、最新のオプティマイザは実行プランを作成する前にそれらすべてにコストをかけます。
実用的なアドバイス:外部キーとして使用できる場合は、インデックスを作成して、オプティマイザがインデックス戦略を利用できるようにします。
以前は、MSSQLオプティマイザーよりも賢いものでした。これは2つのバージョン前に変更されました。今、それは一般的に私に教えます。非常に現実的な意味では、エキスパートシステムであり、ルールベースのシステムが効果的であるほど十分に閉じているドメイン内の多くの非常に賢い人々のすべての知恵を成文化しています。
「Bollocks」は無傷だったのかもしれません。私は傲慢さが少なくなるように求められ、数学は嘘をつかないことを思い出します。これは真実ですが、数学モデルのすべての影響が必ずしも文字どおりに解釈されるべきではありません。負の数の平方根は、それらの不条理を慎重に調べることを避け(そこに駄目)、方程式を解釈する前にそれらをすべてキャンセルすることを確認する場合に非常に便利です。
私がひどく対応した理由は、言葉のとおり、
結合はデカルト積です...
これは意図したものではないかもしれませんが、書かれたものであり、断固として真実ではありません。デカルト積は関係です。結合は関数です。より具体的には、結合は関係値関数です。空の述語を使用すると、デカルト積が生成されます。生成されることをチェックすることは、データベースクエリエンジンの正当性チェックの1つですが、実際には制約のない結合は、教室の外には実用的でないため、誰も書き込みません。
モデルをモデル化されたものと混同するという古代の罠に読者が陥りたくないので、私はこれを呼び出しました。モデルは近似であり、操作を簡単にするために意図的に簡略化されています。
テーブルスキャン結合戦略の選択のカットオフは、データベースエンジン間で異なる場合があります。これは、ツリーノードのフィルファクター、キー値のサイズ、アルゴリズムの微妙さなど、実装に関する多くの決定の影響を受けますが、大まかに言えば、高性能インデックス付けの実行時間はk log n + cです。C項は、主にセットアップ時間で構成される固定オーバーヘッドであり、曲線の形状は、nが数百になるまで(線形探索と比較して)利益を得られないことを意味します。
時々非正規化は良い考えです
非正規化は、特定の結合戦略への取り組みです。前述のように、これは他の結合戦略に干渉します。しかし、ディスクスペースのバケット、予測可能なアクセスパターン、およびそのほとんどまたはすべてを処理する傾向がある場合、結合の事前計算は非常に価値があります。
操作で通常使用するアクセスパスを把握し、それらのアクセスパスのすべての結合を事前計算することもできます。これは、データウェアハウスの背後にある前提です。または、少なくとも、流行語のコンプライアンスのためだけでなく、自分たちがしていることをしている理由を知っている人々によって構築されている場合です。
適切に設計されたデータウェアハウスは、正規化されたトランザクション処理システムからの一括変換によって定期的に生成されます。このように操作データベースとレポートデータベースを分離すると、OLTPとOLAP(オンライントランザクション処理、つまりデータ入力、およびオンライン分析処理、つまりレポート)の衝突をなくすという非常に望ましい効果があります。
ここで重要な点は、定期的な更新とは別に、データウェアハウスは読み取り専用であることです。これは、更新異常の問題を疑わしくします。
OLTPデータベース(データ入力が行われるデータベース)を非正規化するミスを犯さないでください。課金実行の方が高速かもしれませんが、そうすると更新の異常が発生します。Reader's Digestに送信を停止させようとしたことがありますか?
最近のディスク容量は安いので、気を付けてください。しかし、非正規化はデータウェアハウスの話の一部にすぎません。はるかに大きなパフォーマンスの向上は、事前に計算された積み上げ値から得られます。月次の合計などです。それは常にワーキングセットを削減することです。
型の不一致に関するADO.NETの問題
varchar型のインデックス付き列を含むSQL Serverテーブルがあり、AddWithValueを使用して、この列に対するクエリを制約するパラメーターを渡すとします。C#文字列はUnicodeであるため、推定されるパラメーターの型はNVARCHARとなり、VARCHARと一致しません。
VARCHARからNVARCHARへの変換は拡大変換であるため、暗黙的に行われますが、インデックス付けに別れを告げ、その理由をうまく調べてください。
「ディスクヒットをカウントする」(Rick James)
すべてがRAMにキャッシュされている場合は、JOINs
かなり安価です。つまり、正規化によるパフォーマンスの低下はそれほどありません。
「正規化された」スキーマがJOINs
ディスクを頻繁にヒットするが、同等の「非正規化された」スキーマがディスクをヒットする必要がない場合、非正規化はパフォーマンスの競争に勝ちます。
元の作者からのコメント:現代のデータベースエンジンは、アクセスシーケンスの編成に非常に優れており、結合操作中のキャッシュミスを最小限に抑えます。上記は真実ではありますが、大規模なデータでは結合が必然的に問題としてコストがかかることを意味すると誤解される可能性があります。これは、経験の浅い開発者の意思決定を悪化させることになります。