PREWHERE puede hacer que el filtrado sea más eficiente al reducir la cantidad de datos leídos. De forma predeterminada, ClickHouse aplica esta optimización incluso cuando una consulta no especifica explícitamente PREWHERE, trasladando las condiciones aptas de WHERE a PREWHERE. Puede especificar PREWHERE explícitamente para controlar qué condiciones se aplican en esta fase.
Con PREWHERE, ClickHouse primero lee solo las columnas necesarias para evaluar la condición. Después, lee las demás columnas requeridas por la consulta únicamente en los bloques que contienen al menos una fila coincidente. Esto puede reducir la cantidad de datos leídos cuando la condición usa menos columnas que el resto de la consulta y descarta muchos bloques.
Control manual de PREWHERE
PREWHERE manualmente cuando una condición haga referencia a un número reducido de columnas y descarte muchas filas. Esto puede reducir la cantidad de datos que se leen de las columnas restantes.
Una consulta puede contener tanto PREWHERE como WHERE. En este caso, PREWHERE se evalúa primero.
Establezca optimize_move_to_prewhere en 0 para impedir que ClickHouse mueva automáticamente condiciones de WHERE a PREWHERE.
En las consultas con el modificador FINAL, ClickHouse mueve condiciones de WHERE a PREWHERE solo cuando están habilitados tanto optimize_move_to_prewhere como optimize_move_to_prewhere_if_final.
De forma predeterminada,
PREWHERE se evalúa antes de FINAL, por lo que las consultas FROM ... FINAL pueden producir resultados inesperados cuando PREWHERE hace referencia a columnas que no forman parte de la clave ORDER BY de la tabla.PREWHERE con JOIN
PREWHERE en una consulta con un JOIN puede hacer referencia directamente a columnas de una sola tabla como máximo. ClickHouse aplica la condición a las filas de esa tabla antes de que lleguen a la unión.
En cambio, una condición WHERE filtra lógicamente el resultado de la unión, aunque el optimizador puede aplicarla antes de la unión si hacerlo no cambia el resultado. Por lo tanto, usar la misma condición en PREWHERE y WHERE puede producir resultados diferentes, especialmente con uniones externas.
El siguiente ejemplo crea dos tablas para mostrar esta diferencia:
PREWHERE filtra table_2 antes del LEFT JOIN, por lo que la fila de table_1 con id = 1 queda sin coincidencia:
WHERE filtra el resultado de la unión y elimina la fila con id = 1:
Limitaciones
PREWHERE solo se admite en tablas de la familia *MergeTree.