跳转到主要内容
Prewhere 是一种用于更高效执行过滤的优化机制。即使未显式指定 PREWHERE 子句,它默认也是启用的。其工作方式是自动将 WHERE 条件中的一部分移到 prewhere 阶段。PREWHERE 子句的作用仅在于控制这一优化:如果你认为自己比默认行为更清楚如何处理,就可以手动干预。 启用 prewhere 优化后,系统起初只会读取执行 prewhere 表达式所需的列。随后,再读取执行查询其余部分所需的其他列,但仅限于那些至少有某些行使 prewhere 表达式为 true 的块。如果有大量块中 prewhere 表达式对所有行都为 false,并且 prewhere 所需的列少于查询其他部分所需的列,那么这通常可以在查询执行时显著减少从磁盘读取的数据量。

手动控制 PREWHERE

该子句与 WHERE 子句含义相同。区别在于从表中读取哪些数据。对于查询中只有少数列会用到、但能显著过滤数据的过滤条件,可以手动将其放到 PREWHERE 中,从而减少需要读取的数据量。 一个查询可以同时指定 PREWHEREWHERE。在这种情况下,PREWHERE 会先于 WHERE 执行。 如果 optimize_move_to_prewhere 设置为 0,则会禁用将表达式的一部分从 WHERE 自动移到 PREWHERE 的启发式规则。 如果查询带有 FINAL modifier,PREWHERE 优化并不总是正确的。只有当 optimize_move_to_prewhereoptimize_move_to_prewhere_if_final 这两个设置都启用时,才会启用该优化。
PREWHERE 部分会在 FINAL 之前执行,因此,如果对不在表的 ORDER BY 部分中的字段使用 PREWHEREFROM ... FINAL 查询的结果可能会出现偏差。

限制

PREWHERE 仅受 *MergeTree 家族的表支持。

示例

最后修改于 2026年7月2日