Lorsqu'une table dérivée ne peut pas être fusionnée avec la requête externe, la base de données matérialise d'abord l'intégralité de cette table avant de filtrer les lignes selon la condition WHERE. Pour les requêtes complexes impliquant de volumineuses tables dérivées, cette approche traite bien plus de données que nécessaire. PolarDB for MySQL propage directement les conditions WHERE dans les tables dérivées lors de la matérialisation, réduisant ainsi le nombre de lignes traitées et améliorant les performances des requêtes.
Versions prises en charge
Pour utiliser cette fonctionnalité, votre cluster doit exécuter l'une des versions suivantes. Pour vérifier votre version, consultez Query the engine version.
MySQL 8.0.1, version de révision 8.0.1.1.42 ou ultérieure
MySQL 8.0.2, version de révision 8.0.2.2.10 ou ultérieure
Fonctionnement
PolarDB for MySQL étend les capacités de propagation des conditions de MySQL Community Edition avec les améliorations suivantes :
Transfert par équivalence : Les conditions se transfèrent via des relations de colonnes équivalentes. Si
t1.a = d_tab.xett1.a > 6, la conditionx > 6est déduite et propagée dans la table dérivée.Prise en charge de UNION : Les conditions sont propagées uniquement dans la branche correspondante d'une table dérivée UNION.
Cascade avec HAVING vers WHERE : Cette fonctionnalité opère conjointement avec la fonctionnalité HAVING to WHERE afin de propager davantage les conditions via des chaînes d'équivalence.
Limites
Une condition WHERE ne peut être propagée vers une table dérivée que si toutes les conditions suivantes sont remplies :
Toutes les colonnes (ou leurs équivalents) présentes dans la condition proviennent d'une table dérivée matérialisée.
La table dérivée ne contient aucune clause LIMIT.
-
Aucune colonne de la condition WHERE externe ou de la colonne mappée de la table matérialisée ne répond aux critères suivants :
Être générée par une sous-requête ou avoir une valeur non déterministe (la même entrée peut retourner des résultats différents).
Être une procédure stockée ou une fonction stockée.
Configuration de la propagation WHERE vers les tables dérivées
Définissez le paramètre loose_derived_cond_pushdown_mode pour contrôler cette fonctionnalité au niveau global. Pour obtenir des instructions sur la configuration des paramètres, consultez Configure cluster and node parameters.
| Paramètre | Niveau | Description |
|---|---|---|
loose_derived_cond_pushdown_mode |
Global | Contrôle la propagation des conditions WHERE vers les tables dérivées. Valeurs valides : OFF (désactivé), ON (activé sur tous les nœuds), REPLICA_ON (activé uniquement sur les nœuds en lecture seule, valeur par défaut). |
Pour activer la fonctionnalité uniquement pour la session en cours, exécutez :
SET optimizer_switch="derived_condition_pushdown=on";
SET derived_cond_pushdown_mode=on;
Exemples
Les exemples suivants illustrent la transformation des requêtes par PolarDB for MySQL lorsque la propagation des conditions est active. Chaque exemple présente la requête d'origine et son équivalent optimisé.
Exemple 1 : Propagation par transfert d'équivalence
Lorsque la clause WHERE externe contient une condition d'équivalence (t1.a = d_tab.x), PolarDB déduit la condition implicite (x > 6) et la propage dans la table dérivée. Cela permet d'éliminer des lignes de la table dérivée avant la jointure plutôt que de filtrer après une matérialisation complète.
Requête d'origine :
SELECT *
FROM t1, (
SELECT x
FROM t2
GROUP BY x
) d_tab, t2
WHERE t1.a = d_tab.x
AND t1.a > 6;
Requête optimisée (la condition x > 6 est propagée dans la table dérivée) :
SELECT *
FROM t1, (
SELECT x
FROM t2
WHERE x > 6
GROUP BY x
) d_tab
WHERE t1.a = d_tab.x
AND t1.a > 6;
Exemple 2 : Propagation dans une table dérivée UNION
Si la table dérivée est un UNION, PolarDB propage la condition uniquement dans les branches éligibles. Dans cet exemple, la condition f2 = 1 est propagée dans la seconde branche du UNION.
Requête d'origine :
SELECT f1
FROM (
SELECT (
SELECT f1
FROM t1
LIMIT 1
) AS f1
FROM t1
UNION
SELECT f2
FROM t2
) dt
WHERE f1 = 1;
Requête optimisée (la condition f2 = 1 est propagée dans la branche UNION éligible) :
SELECT f1
FROM (
SELECT (
SELECT f1
FROM t1
LIMIT 1
) AS f1
FROM t1
UNION
SELECT f2
FROM t2
WHERE f2 = 1
) dt
WHERE f1 = 1;
Exemple 3 : Cascade avec HAVING vers WHERE
Utilisée conjointement avec la fonctionnalité HAVING to WHERE, cette option permet de cascader davantage les conditions propagées depuis HAVING vers la table dérivée. Dans cet exemple, f1 < 3 passe de HAVING à WHERE, puis est propagée dans la table dérivée.
Requête d'origine :
SELECT *
FROM (
SELECT f1, f2
FROM t1
) dt
GROUP BY f1
HAVING f1 < 3
AND f2 > 11
AND MAX(f3) > 12;
Requête optimisée (f1 < 3 est propagée dans la table dérivée ; f2 > 11 et MAX(f3) > 12 restent dans HAVING) :
SELECT *
FROM (
SELECT f1, f2
FROM t1
WHERE f1 < 3
) dt
WHERE f1 < 3
GROUP BY f1
HAVING f2 > 11
AND MAX(f3) > 12;
Étapes suivantes
Condition pushdown (HAVING to WHERE) — à utiliser conjointement avec la propagation WHERE vers les tables dérivées pour une cascade de conditions plus poussée.
Configure cluster and node parameters — pour définir
loose_derived_cond_pushdown_modeau niveau global.Query the engine version — pour confirmer la version de votre cluster avant d'activer la fonctionnalité.