PREWHERE子句
Prewhere是一种优化,用于更有效地应用过滤。即使未显式指定PREWHERE
子句,它默认为启用状态。它的工作原理是自动将部分WHERE条件移动到prewhere阶段。PREWHERE
子句的作用仅是控制这种优化,如果你认为自己知道如何比默认情况更好地处理它。
通过prewhere优化,最初仅读取执行prewhere表达式所需的列。然后读取其他列,以运行查询的其余部分,但仅限于那些在某些行中prewhere表达式为true
的区块。如果存在许多区块,其中所有行的prewhere表达式均为false
,并且prewhere所需的列少于查询的其他部分,这通常允许从磁盘中读取更少的数据以执行查询。
手动控制Prewhere
该子句的含义与WHERE
子句相同。区别在于从表中读取的数据。当手动控制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
之前执行,因此在使用不在表的ORDER BY
部分中的字段的FROM ... FINAL
查询时,结果可能会偏斜。
限制
PREWHERE
仅支持来自*MergeTree家族的表。