PREWHERE pode tornar a filtragem mais eficiente ao reduzir a quantidade de dados lidos. Por padrão, o ClickHouse aplica essa otimização mesmo quando uma consulta não especifica PREWHERE explicitamente, movendo condições qualificadas de WHERE para PREWHERE. Você pode especificar PREWHERE explicitamente para controlar quais condições são aplicadas nessa etapa.
Com PREWHERE, o ClickHouse primeiro lê apenas as colunas necessárias para avaliar a condição. Em seguida, lê as demais colunas exigidas pela consulta apenas nos blocos que contêm pelo menos uma linha correspondente. Isso pode reduzir a quantidade de dados lidos quando a condição usa menos colunas do que o restante da consulta e elimina muitos blocos.
Controle manual de PREWHERE
PREWHERE manualmente quando uma condição fizer referência a poucas colunas e filtrar muitas linhas. Isso pode reduzir a quantidade de dados lidos das colunas restantes.
Uma consulta pode conter tanto PREWHERE quanto WHERE. Nesse caso, PREWHERE é avaliado primeiro.
Defina optimize_move_to_prewhere como 0 para impedir que o ClickHouse mova condições automaticamente de WHERE para PREWHERE.
Para consultas com o modificador FINAL, o ClickHouse move condições de WHERE para PREWHERE somente quando optimize_move_to_prewhere e optimize_move_to_prewhere_if_final estão habilitados.
Por padrão,
PREWHERE é avaliado antes de FINAL; portanto, consultas FROM ... FINAL podem produzir resultados inesperados quando PREWHERE faz referência a colunas fora da chave ORDER BY da tabela.PREWHERE com JOIN
PREWHERE em uma consulta com um JOIN pode referenciar diretamente colunas de, no máximo, uma tabela. O ClickHouse aplica a condição às linhas dessa tabela antes que elas sejam incluídas na junção.
Por outro lado, uma condição WHERE filtra logicamente o resultado da junção, embora o otimizador possa aplicá-la antes da junção quando isso não altera o resultado. Portanto, usar a mesma condição em PREWHERE e WHERE pode produzir resultados diferentes, especialmente com junções externas.
O exemplo a seguir cria duas tabelas para demonstrar essa diferença:
PREWHERE filtra table_2 antes do LEFT JOIN, de modo que a linha de table_1 com id = 1 fica sem correspondência:
WHERE filtra o resultado do JOIN, removendo a linha com id = 1:
Limitações
PREWHERE é suportado apenas por tabelas da família *MergeTree.