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

> Documentation de la clause PREWHERE

# Clause PREWHERE

Prewhere est une optimisation qui permet d’appliquer le filtrage plus efficacement. Elle est activée par défaut, même si la clause `PREWHERE` n’est pas explicitement spécifiée. Elle fonctionne en déplaçant automatiquement une partie de la condition [WHERE](/fr/reference/statements/select/where) vers l’étape prewhere. Le rôle de la clause `PREWHERE` est uniquement de contrôler cette optimisation si vous pensez savoir mieux l’appliquer que le comportement par défaut.

Avec l’optimisation prewhere, seules les colonnes nécessaires à l’exécution de l’expression prewhere sont d’abord lues. Ensuite, les autres colonnes nécessaires à l’exécution du reste de la requête sont lues, mais uniquement dans les blocs où l’expression prewhere vaut `true` pour au moins certaines lignes. S’il existe de nombreux blocs où l’expression prewhere vaut `false` pour toutes les lignes, et si prewhere nécessite moins de colonnes que les autres parties de la requête, cela permet souvent de lire beaucoup moins de données depuis le disque pour exécuter la requête.

<div id="controlling-prewhere-manually">
  ## Contrôle manuel de PREWHERE
</div>

Cette clause a la même signification que la clause `WHERE`. La différence réside dans les données lues depuis la table. Le contrôle manuel de `PREWHERE` est utile pour les conditions de filtrage utilisées par une minorité des colonnes de la requête, mais qui offrent un fort pouvoir de filtration des données. Cela réduit le volume de données à lire.

Une requête peut spécifier simultanément `PREWHERE` et `WHERE`. Dans ce cas, `PREWHERE` est appliqué avant `WHERE`.

Si le paramètre [optimize\_move\_to\_prewhere](/fr/reference/settings/session-settings#optimize_move_to_prewhere) est défini sur 0, les heuristiques qui déplacent automatiquement des parties d’expressions de `WHERE` vers `PREWHERE` sont désactivées.

Si la requête utilise le modificateur [FINAL](/fr/reference/statements/select/from#final-modifier), l’optimisation `PREWHERE` n’est pas toujours correcte. Elle n’est activée que si les deux paramètres [optimize\_move\_to\_prewhere](/fr/reference/settings/session-settings#optimize_move_to_prewhere) et [optimize\_move\_to\_prewhere\_if\_final](/fr/reference/settings/session-settings#optimize_move_to_prewhere_if_final) sont activés.

<Note>
  La section `PREWHERE` est exécutée avant `FINAL` ; les résultats des requêtes `FROM ... FINAL` peuvent donc être faussés lors de l’utilisation de `PREWHERE` avec des champs qui ne figurent pas dans la section `ORDER BY` d’une table.
</Note>

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

-- let's enable tracing to see which predicate are moved to PREWHERE
set send_logs_level='debug';

MergeTreeWhereOptimizer: condition "B = 0" moved to PREWHERE  
-- Clickhouse moves automatically `B = 0` to PREWHERE, but it has no sense because B is always 0.

-- Let's move other predicate `C = 'x'` 

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

-- This query with manual `PREWHERE` processes slightly less data: 158.89 MB VS 168.89 MB
```
