Секция PREWHERE
Prewhere — это оптимизация для более эффективного применения фильтрации. Она включена по умолчанию, даже если секция PREWHERE
явно не указана. В этом случае работает автоматическое перемещение части выражения из WHERE до стадии prewhere. Роль секции PREWHERE
только для управления этой оптимизацией, если вы думаете, что знаете, как сделать перемещение условия лучше, чем это происходит по умолчанию.
При оптимизации prewhere сначала читаются только те столбцы, которые необходимы для выполнения выражения prewhere. Затем читаются другие столбцы, необходимые для выполнения остальной части запроса, но только те блоки, в которых находится выражение prewhere «верно» по крайней мере для некоторых рядов. Если есть много блоков, где выражение prewhere «ложно» для всех строк и для выражения prewhere требуется меньше столбцов, чем для других частей запроса, это часто позволяет считывать гораздо меньше данных с диска для выполнения запроса.
Управление PREWHERE вручную
PREWHERE
имеет смысл использовать, если есть условия фильтрации, которые использует меньшинство столбцов из тех, что есть в запросе, но достаточно сильно фильтрует данные. Таким образом, сокращается количество читаемых данных.
В запросе могут быть одновременно указаны и PREWHERE
, и WHERE
. В этом случае PREWHERE
предшествует WHERE
.
Если значение параметра optimize_move_to_prewhere равно 0, эвристика по автоматическому перемещению части выражений из WHERE
к PREWHERE
отключается.
Если в запросе есть модификатор FINAL, оптимизация PREWHERE
не всегда корректна. Она действует только если включены обе настройки optimize_move_to_prewhere и optimize_move_to_prewhere_if_final.
Секция PREWHERE
выполняется до FINAL
, поэтому результаты запросов FROM ... FINAL
могут исказиться при использовании PREWHERE
с полями, не входящями в ORDER BY
таблицы.
Ограничения
PREWHERE
поддерживается только табличными движками из семейства *MergeTree.