PREWHERE n’est pas explicitement spécifiée. Elle fonctionne en déplaçant automatiquement une partie de la condition 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.
Contrôle manuel de PREWHERE
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 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, l’optimisation PREWHERE n’est pas toujours correcte. Elle n’est activée que si les deux paramètres optimize_move_to_prewhere et optimize_move_to_prewhere_if_final sont activés.
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.Limitations
PREWHERE n’est pris en charge que par les tables de la famille *MergeTree.