概要
上記の I/O 最適化によって読み取るデータ量は大幅に減らせますが、それでも
WHERE 句を通過した行については、ソート、集約、LIMIT などの処理を実行する前に、すべてのカラムを読み込むことが前提になっています。では、一部のカラムはもっと後の段階まで不要だったり、WHERE 句を通過しても実際にはまったく使われなかったりする場合はどうでしょうか。
そこで登場するのが遅延マテリアライゼーションです。これは、I/O 最適化の仕組みを完成させる独立した拡張です。
- 索引と
PREWHEREを組み合わせることで、WHERE句のカラムフィルターに一致する行だけが処理されるようになります。 - 遅延マテリアライゼーションはこれをさらに進め、クエリ実行計画で実際に必要になるまでカラムの読み取りを遅らせます。
フィルタリング後であっても、次の処理 - たとえばソート - に必要なカラムだけがすぐに読み込まれます。
それ以外は後回しにされ、
LIMITがあるため、多くの場合は最終結果を生成するのに必要な分だけしか読み込まれません。 このため、遅延マテリアライゼーションは Top N クエリで特に効果的です。最終結果に必要なのが、特定の、しかもしばしば大きなカラムからのごく少数の行だけであるケースが多いためです。
実例
PREWHERE の恩恵を受けるには、クエリにフィルターが必要です。索引には主キーのカラムに対するフィルターが、PREWHERE には任意のカラムに対するフィルターが必要になります。
遅延マテリアライゼーションはその上に自然に重ねて適用できますが、前述のほかの最適化とは異なり、カラムフィルターがまったくないクエリでも高速化できます。
次のクエリ例では、日付、製品、評価、認証済みかどうかに関係なく、Amazon レビューのうち「参考になった」票の数が最も多いものを探し、上位 3 件についてタイトル、見出し、本文全文を返します。
まず、遅延マテリアライゼーションを無効にした状態で、クエリを実行します (コールドなファイルシステムキャッシュを使用し、query_plan_optimize_lazy_materialization を使用) :
Query
Response
Query
Response
クエリ実行計画で遅延マテリアライゼーションを確認する方法
EXPLAIN 句を使用してクエリの論理実行計画を確認することで確認できます。