Обзор
Хотя перечисленные выше оптимизации 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: