Skip to main content
PREWHERE 可通过减少读取的数据量提高筛选效率。默认情况下,即使查询未显式指定 PREWHERE,ClickHouse 也会将符合条件的条件从 WHERE 移至 PREWHERE,从而应用此优化。您可以显式指定 PREWHERE,以控制在此阶段应用哪些条件。 使用 PREWHERE 时,ClickHouse 首先仅读取评估条件所需的列。随后,仅对包含至少一行匹配数据的块读取查询所需的其他列。当条件使用的列少于查询其余部分所需的列,且能筛除大量块时,可减少读取的数据量。

手动控制 PREWHERE

当条件仅涉及少量列且能过滤掉大量行时,可手动指定 PREWHERE。这样可以减少读取其余列的数据量。 一个查询可以同时包含 PREWHEREWHERE。在这种情况下,会先计算 PREWHERE optimize_move_to_prewhere 设置为 0,以防止 ClickHouse 自动将条件从 WHERE 移至 PREWHERE 对于带有 FINAL 修饰符的查询,只有在 optimize_move_to_prewhereoptimize_move_to_prewhere_if_final 均已启用时,ClickHouse 才会将条件从 WHERE 移至 PREWHERE
默认情况下,PREWHERE 会在 FINAL 之前计算。因此,当 PREWHERE 引用了表的 ORDER BY 键以外的列时,FROM ... FINAL 查询可能会产生意外结果。

PREWHEREJOIN

在包含 JOIN 的查询中,PREWHERE 条件最多只能直接引用一个表的列。ClickHouse 会在该表的行参与联接前对其应用该条件。 相比之下,WHERE 条件在逻辑上会过滤联接后的结果;但只要不改变结果,优化器也可能在联接前应用该条件。因此,在 PREWHEREWHERE 中使用相同条件可能会产生不同结果,尤其是在外联接时。 以下示例创建两个表来说明这一差异:
在第一个查询中,PREWHERE 会在 LEFT JOIN 之前对 table_2 进行过滤,因此 table_1id = 1 的行仍无法匹配:
WHERE 中使用相同条件会对 join 结果进行过滤,移除 id = 1 的行:

限制

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

示例

最后修改于 2026年8月14日