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
之前执行,因此在使用 PREWHERE
结合未在表的 ORDER BY
部分的字段时,FROM ... FINAL
查询的结果可能会出现偏差。
限制
PREWHERE
仅支持来自 *MergeTree 家族的表。