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 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.
Contrôler manuellement PREWHERE
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 sur 0 pour empêcher ClickHouse de déplacer automatiquement les conditions de WHERE vers PREWHERE.
Pour les requêtes utilisant le modificateur FINAL, ClickHouse ne déplace les conditions de WHERE vers PREWHERE que lorsque optimize_move_to_prewhere et optimize_move_to_prewhere_if_final sont tous deux activés.
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.PREWHERE avec JOIN
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 :
PREWHERE filtre table_2 avant le LEFT JOIN, de sorte que la ligne de table_1 avec id = 1 reste sans correspondance :
WHERE filtre le résultat de la jointure et supprime la ligne avec id = 1 :
Limitations
PREWHERE n’est pris en charge que par les tables de la famille *MergeTree.