まず第一に、これらは異なる目的に適した2つの異なるデータモデルです。
そうは言っても、データがよりコンパクトにパックされているため、必要なI / Oが少なくて済むため、2番目のモデルの方が集計が高速になると思います。
- 最初のモデルのGROUPBYは、フルで満たすことができます インデックスをスキャンする
{size, price}
。データが大きすぎてRAMに収まらない場合、インデックスの代替手段は遅すぎます。 - 2番目のモデルのクエリは、全表スキャンで満たすことができます。インデックスは必要ありません。
最初のアプローチではテーブル+インデックスが必要であり、2番目のアプローチではテーブルのみが必要なため、2番目のケースではキャッシュ使用率が高くなります。キャッシングを無視して、最初のモデルのインデックス(テーブルなし)を2番目のモデルのテーブルと比較しても、size
を物理的に記録しているという理由だけで、インデックスはテーブルよりも大きくなると思われます。 また、Bツリーに典型的な未使用の「穴」があります(ただし、テーブルがクラスター化
。
そして最後に、2番目のモデルには、INSERT / UPDATE/DELETEのパフォーマンスに影響を与える可能性のあるインデックスメンテナンスのオーバーヘッドがありません。
それ以外に、SUMとCOUNTを1行だけを含む別のテーブルにキャッシュすることを検討できます。メインテーブルで行が挿入、更新、または削除されるたびに、トリガーを介してSUMとCOUNTの両方を更新します。 SUMとCOUNTを除算するだけで、現在のAVGを簡単に取得できます。
しかし、実際には測定する必要があります 確かに代表的な量のデータについて。
クエリにはWHERE句がないため、すべての行がスキャンされます。インデックスは、テーブルの行の比較的小さなサブセットを取得する場合にのみ役立ちます(場合によっては、インデックスのみのスキャン )。大まかな目安として、テーブル内の行の10%以上が必要な場合、インデックスは役に立ちません。また、DBMSは、インデックスが使用可能な場合でも、全表スキャンを選択することがよくあります。