インタビュアーが私にこの質問をしました:
テーブルは適切な正規化ルールで作成されますが、データベースのパフォーマンスが低下しています。 [つまり、select、insertステートメントで処理が完了するまでに時間がかかっています。]データベースのパフォーマンスを向上させるために検討する必要がある領域は何ですか。
明らかにこれは漠然とした質問です。正規化されていても、データベースの実行速度が遅い場合、どのような問題が発生する可能性がありますか?
インタビュアーはデータサイエンティストの回答を探していたのではなく、単に「正規化」!=「パフォーマンス」を理解していることを確認するために探していたように思えます。だから私は彼が望んでいたと思うレベルでこの答えを保持します。
正規化とは、保存されたデータの冗長性を最小限に抑えることを意味します。代わりに、複数のテーブル間のリレーションシップ(多くの場合、外部制約を伴う)をセットアップします。ただし、正規化によって格納されるデータの量は少なくなる可能性がありますが、多くのクエリが最終的に複数のテーブルを結合するため、パフォーマンスの問題が発生することがよくあります。複数のテーブルを一度に更新する必要がある場合にデータを追加する場合も同様です。
多くの場合、データを非正規化することで速度が向上します。さらに多くのデータを保存していて、重複している可能性がありますが、最も頻繁に使用されるクエリを実行すると、すべてのデータが1つのテーブルに格納されます。 1つのテーブルから結果を取得することは、通常、ハードウェアで複数のテーブルを結合するよりもはるかに簡単です。
INSERTステートメントをより高速に実行することは、少し難解な技術です。しかし、それはおそらく焦点ではありません。データベースの目的は、データをデータベースに入れることではありません。それは興味深く有用な方法でそれを取り戻しています。したがって、主に注目するのはSELECTステートメントです。
最初に確認するのは、遅いクエリのクエリプランを確認することです。時間のかなりの割合を占めているテーブルスキャンがあるかどうかを確認します。テーブルスキャンとは、データベースエンジンがすべての行を個別に調べて、WHERE条件を満たすかどうかを確認する必要がある場合です。これらのいずれかが見つかった場合は、適切なWHERE基準でテーブルにインデックスを付けることにより、クエリをより高速に実行できます。これは、O(N)からO(log N)またはO(1)までの検索時間を要する可能性があります。
いくつかのデータベースはあなたを簡単にします:それらのクエリプランアナライザーは、インデックスが欠落していることを指摘し、作成すべきものを提案します。
また、クエリの結合を確認してください。結合基準が広すぎないことを確認し、完全結合が機能するときに左外部結合を使用しないように注意してください。これらの問題の両方が原因で、不適切に作成されたクエリが生成する行が多すぎ、実行に時間がかかる可能性があります。
インデックスの欠落や不適切な結合がない場合、より高度なトリックは非正規化です:他のテーブルにあるデータを複製するテーブルに列を設定して、結合や集計を回避できます。それは高価になる可能性があります。ただし、これはトリガーを使用して慎重に行う必要があります。これにより、データの同期が維持され、何をしているのかがわかっていて、より良い代替手段がない場合にのみ行うのが最善です。
具体的には、クエリ実行プランで、インデックスシークではなくテーブルスキャンであるアクションを探します。外部キーを表す列を示すためにインデックスを追加する必要があるかもしれません(自動的に作成されません)。
その他のオプションは、データファイルを別の物理ディスクに配置することです。パーティションにRAIDを使用することもできます。少なくとも、ログファイルをデータファイルから分離したいので、ログへの書き込みがデータファイルへの書き込み時間に影響を与えないようにします。
より高度なシナリオには、検索の負荷を複数のノードに分散できるようにするクラスタリングとシャーディングが含まれます。