> ## 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.

> Documentation de la clause PREWHERE

# Clause PREWHERE

`PREWHERE` peut rendre le filtrage plus efficace en réduisant la quantité de données lues. Par défaut, ClickHouse applique cette optimisation, même lorsqu'une requête ne spécifie pas explicitement `PREWHERE`, en déplaçant les conditions admissibles de [`WHERE`](/fr/reference/statements/select/where) vers `PREWHERE`. Vous pouvez spécifier explicitement `PREWHERE` pour contrôler les conditions appliquées à cette étape.

Avec `PREWHERE`, ClickHouse lit d'abord uniquement les colonnes nécessaires à l'évaluation de la condition. Il lit ensuite les autres colonnes requises par la requête uniquement pour les blocs contenant au moins une ligne correspondante. Cela peut réduire la quantité de données lues lorsque la condition utilise moins de colonnes que le reste de la requête et élimine de nombreux blocs.

<div id="controlling-prewhere-manually">
  ## Contrôler manuellement `PREWHERE`
</div>

Spécifiez manuellement `PREWHERE` lorsqu'une condition porte sur un petit nombre de colonnes et élimine de nombreuses lignes. Cela peut réduire la quantité de données lues pour les colonnes restantes.

Une requête peut contenir à la fois `PREWHERE` et `WHERE`. Dans ce cas, `PREWHERE` est évalué en premier.

Définissez [`optimize_move_to_prewhere`](/fr/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere) sur `0` pour empêcher ClickHouse de déplacer automatiquement les conditions de `WHERE` vers `PREWHERE`.

Pour les requêtes utilisant le modificateur [`FINAL`](/fr/reference/statements/select/from#final-modifier), ClickHouse ne déplace les conditions de `WHERE` vers `PREWHERE` que lorsque [`optimize_move_to_prewhere`](/fr/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere) et [`optimize_move_to_prewhere_if_final`](/fr/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere_if_final) sont tous deux activés.

<Note>
  Par défaut, `PREWHERE` est évalué avant `FINAL` ; les requêtes `FROM ... FINAL` peuvent donc produire des résultats inattendus lorsque `PREWHERE` porte sur des colonnes ne faisant pas partie de la clé `ORDER BY` de la table.
</Note>

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

Dans une requête contenant un [`JOIN`](/fr/reference/statements/select/join), une condition `PREWHERE` ne peut référencer directement les colonnes que d'une seule table au plus. ClickHouse applique la condition aux lignes de cette table avant qu'elles ne soient jointes.

À l'inverse, une condition `WHERE` filtre logiquement le résultat de la jointure, bien que l'optimiseur puisse l'appliquer avant la jointure lorsque cela ne modifie pas le résultat. Utiliser la même condition dans `PREWHERE` et `WHERE` peut donc produire des résultats différents, en particulier avec les jointures externes.

L'exemple suivant crée deux tables pour illustrer cette différence :

```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');
```

Dans la première requête, `PREWHERE` filtre `table_2` avant le `LEFT JOIN`, de sorte que la ligne de `table_1` avec `id = 1` reste sans correspondance :

```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             │
   └────┴───────┴───────────────┘
```

L’utilisation de la même condition dans `WHERE` filtre le résultat de la jointure et supprime la ligne avec `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">
  ## Limitations
</div>

`PREWHERE` n’est pris en charge que par les tables de la famille [\*MergeTree](/fr/reference/engines/table-engines/mergetree-family/index).

<div id="example">
  ## Exemple
</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.
```
