> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentação da cláusula PREWHERE

# Cláusula PREWHERE

`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`](/pt-BR/reference/statements/select/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.

<div id="controlling-prewhere-manually">
  ## Controle manual de `PREWHERE`
</div>

Especifique `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`](/pt-BR/reference/settings/session-settings/optimize-move-to-prewhere#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`](/pt-BR/reference/statements/select/from#final-modifier), o ClickHouse move condições de `WHERE` para `PREWHERE` somente quando [`optimize_move_to_prewhere`](/pt-BR/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere) e [`optimize_move_to_prewhere_if_final`](/pt-BR/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere_if_final) estão habilitados.

<Note>
  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.
</Note>

<div id="prewhere-with-join">
  ## `PREWHERE` com `JOIN`
</div>

Uma condição `PREWHERE` em uma consulta com um [`JOIN`](/pt-BR/reference/statements/select/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:

```sql theme={null}
CREATE TABLE table_1
(
    `id` UInt32,
    `value` String
)
ENGINE = MergeTree
ORDER BY id;

CREATE TABLE table_2
(
    `id` UInt32,
    `value` String
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO table_1 VALUES (1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO table_2 VALUES (1, 'x'), (2, 'y'), (3, 'z');
```

Na primeira consulta, `PREWHERE` filtra `table_2` antes do `LEFT JOIN`, de modo que a linha de `table_1` com `id = 1` fica sem correspondência:

```sql theme={null}
SELECT
    table_1.id,
    table_1.value,
    table_2.value
FROM table_1
LEFT JOIN table_2 ON table_1.id = table_2.id
PREWHERE table_2.id >= 2
ORDER BY table_1.id;
```

```text theme={null}
   ┌─id─┬─value─┬─table_2.value─┐
1. │  1 │ a     │               │
2. │  2 │ b     │ y             │
3. │  3 │ c     │ z             │
   └────┴───────┴───────────────┘
```

Usar a mesma condição em `WHERE` filtra o resultado do `JOIN`, removendo a linha com `id = 1`:

```sql theme={null}
SELECT
    table_1.id,
    table_1.value,
    table_2.value
FROM table_1
LEFT JOIN table_2 ON table_1.id = table_2.id
WHERE table_2.id >= 2
ORDER BY table_1.id;
```

```text theme={null}
   ┌─id─┬─value─┬─table_2.value─┐
1. │  2 │ b     │ y             │
2. │  3 │ c     │ z             │
   └────┴───────┴───────────────┘
```

<div id="limitations">
  ## Limitações
</div>

`PREWHERE` é suportado apenas por tabelas da família [\*MergeTree](/pt-BR/reference/engines/table-engines/mergetree-family/index).

<div id="example">
  ## Exemplo
</div>

```sql theme={null}
CREATE TABLE mydata
(
    `A` Int64,
    `B` Int8,
    `C` String
)
ENGINE = MergeTree
ORDER BY A AS
SELECT
    number,
    0,
    if(number between 1000 and 2000, 'x', toString(number))
FROM numbers(10000000);

SELECT count()
FROM mydata
WHERE (B = 0) AND (C = 'x');

1 row in set. Elapsed: 0.074 sec. Processed 10.00 million rows, 168.89 MB (134.98 million rows/s., 2.28 GB/s.)

-- Enable tracing to see which predicates are moved to PREWHERE.
set send_logs_level='debug';

MergeTreeWhereOptimizer: condition "B = 0" moved to PREWHERE  
-- ClickHouse automatically moves B = 0 to PREWHERE, but this condition does not filter any rows because B is always 0.

-- Move the more selective C = 'x' predicate to PREWHERE.

SELECT count()
FROM mydata
PREWHERE C = 'x'
WHERE B = 0;

1 row in set. Elapsed: 0.069 sec. Processed 10.00 million rows, 158.89 MB (144.90 million rows/s., 2.30 GB/s.)

-- The query with manually specified PREWHERE processes slightly less data: 158.89 MB instead of 168.89 MB.
```
