Les hints parallèles permettent de contourner l'optimiseur afin de maîtriser le degré de parallélisme (DOP), le comportement des analyses de tables ainsi que les stratégies de distribution pour les jointures, les agrégations et les tris.
Compatibilité des versions
| Version | Hints pris en charge |
|---|---|
| PolarDB for MySQL 8.0.1 | PARALLEL, NO_PARALLEL |
| PolarDB for MySQL 8.0.2 | PARALLEL, NO_PARALLEL, PQ_DISTRIBUTE, PQ_GROUPBY, PQ_DISTINCT, PQ_WINDOW, PQ_ORDERBY |
La version 8.0.2 introduit PQ_DISTRIBUTE pour la distribution des jointures, ainsi que PQ_GROUPBY, PQ_DISTINCT, PQ_WINDOW et PQ_ORDERBY pour définir les modes d'exécution des agrégations et des tris.
Référence rapide
| Hint | Objectif | Version |
|---|---|---|
PARALLEL |
Activez la requête parallèle ; définissez le DOP ou les tables cibles | 8.0.1+ |
NO_PARALLEL |
Désactivez la requête parallèle globalement ou pour des tables spécifiques | 8.0.1+ |
PQ_DISTRIBUTE |
Définissez la méthode de distribution pour les jointures | 8.0.2 |
PQ_GROUPBY |
Spécifiez le mode d'exécution de l'agrégation GROUP BY | 8.0.2 |
PQ_DISTINCT |
Spécifiez le mode d'exécution de l'agrégation DISTINCT | 8.0.2 |
PQ_WINDOW |
Configurez le mode d'exécution des fonctions de fenêtrage | 8.0.2 |
PQ_ORDERBY |
Réglez le mode de tri ORDER BY | 8.0.2 |
PQ_PUSHDOWN |
Exécutez les sous-requêtes en parallèle via la politique de pushdown | - |
NO_PQ_PUSHDOWN |
Exécutez les sous-requêtes en parallèle via la politique d'accès partagé | - |
Activer ou désactiver la requête parallèle
Activation
SELECT /*+PARALLEL(x)*/ ... FROM ...; -- x > 0
SELECT /*+ SET_VAR(max_parallel_degree=n) */ * FROM ... -- n > 0
Désactivation
SELECT /*+NO_PARALLEL()*/ ... FROM ...;
SELECT /*+ SET_VAR(max_parallel_degree=0) */ * FROM ...
PARALLEL et NO_PARALLEL
Ces hints servent à cibler des tables pour une analyse parallèle ou, au contraire, à exclure certaines tables de ce traitement.
Syntaxe
/*+ PARALLEL [( [query_block] [table_name] [degree] )] */
/*+ NO_PARALLEL [( [query_block] [table_name][, table_name] )] */
Paramètres
| Paramètre | Description |
|---|---|
query_block |
Nom du bloc de requête auquel s'applique le hint. |
table_name |
Nom de la table concernée par le hint. |
degree |
Degré de parallélisme (DOP). |
Le hint PARALLEL reste sans effet sur les requêtes ne prenant pas en charge le traitement parallèle, ni sur les tables incompatibles avec les analyses parallèles.
Différences entre PARALLEL() et SET_VAR
Bien que tous deux définissent le DOP, leur comportement diffère quant à l'application forcée du parallélisme :
PARALLEL()impose l'exécution parallèle même si le nombre de lignes de la table est inférieur au seuilrecords_threshold_for_parallelism(valeur par défaut : 10 000).SET_VAR(max_parallel_degree=n)configure le DOP mais n'impose pas l'exécution parallèle lorsque le volume de lignes se situe sous le seuilrecords_threshold_for_parallelism.
Privilégiez PARALLEL() pour garantir le parallélisme indépendamment de la taille des tables. Optez pour SET_VAR si vous souhaitez laisser l'optimiseur décider en fonction du nombre de lignes.
Exemples
Forcer une requête parallèle avec le DOP par défaut
SELECT /*+PARALLEL()*/ * FROM t1, t2;
Cette commande force l'exécution parallèle même si le nombre de lignes est inférieur à records_threshold_for_parallelism (par défaut : 10 000). Le DOP dépend alors de max_parallel_degree. Si max_parallel_degree vaut 0, la requête parallèle est désactivée.
Forcer une requête parallèle avec un DOP spécifique
SELECT /*+PARALLEL(8)*/ * FROM t1, t2;
L'exécution parallèle est imposée avec un DOP de 8, y compris lorsque le nombre de lignes reste sous le seuil records_threshold_for_parallelism.
Définir le DOP via SET_VAR
SELECT /*+ SET_VAR(max_parallel_degree=8) */ * FROM t1, t2;
Cette instruction fixe max_parallel_degree à 8. Contrairement à PARALLEL(), elle ne force pas l'exécution parallèle si le nombre de lignes est inférieur à records_threshold_for_parallelism.
Analyse parallèle sur une table spécifique
SELECT /*+PARALLEL(t1)*/ * FROM t1, t2;
Seule la table t1 fait l'objet d'une analyse parallèle forcée.
SELECT /*+PARALLEL(t1 8)*/ * FROM t1, t2;
Une analyse parallèle est imposée sur t1 avec un DOP fixé à 8.
Sous-requêtes parallèles via des blocs de requête
SELECT /*+PARALLEL(@subq1)*/ SUM(t.a) FROM t WHERE t.a =
(SELECT /*+QB_NAME(subq1)*/ SUM(t1.a) FROM t1);
L'exécution parallèle est forcée pour le bloc de requête nommé subq1, en utilisant la valeur par défaut de max_parallel_degree comme DOP.
SELECT /*+PARALLEL(@subq1 8)*/ SUM(t.a) FROM t WHERE t.a =
(SELECT /*+QB_NAME(subq1)*/ SUM(t1.a) FROM t1);
Le bloc de requête subq1 s'exécute en parallèle avec un DOP explicite de 8.
Sous-requêtes parallèles via des hints inline
SELECT SUM(t.a) FROM t WHERE t.a =
(SELECT /*+PARALLEL()*/ SUM(t1.a) FROM t1);
La sous-requête s'exécute en parallèle selon la valeur par défaut de max_parallel_degree.
SELECT SUM(t.a) FROM t WHERE t.a =
(SELECT /*+PARALLEL(8)*/ SUM(t1.a) FROM t1);
Un DOP de 8 est appliqué pour forcer l'exécution parallèle de la sous-requête.
Désactiver la requête parallèle
SELECT /*+NO_PARALLEL()*/ * FROM t1, t2;
Toute exécution parallèle est désactivée pour l'ensemble de l'instruction.
Désactiver la requête parallèle pour des tables spécifiques
SELECT /*+NO_PARALLEL(t1)*/ * FROM t1, t2;
Les analyses parallèles sont interdites uniquement pour t1. Si la requête parallèle est activée globalement, le système peut toujours effectuer des analyses parallèles sur t2.
SELECT /*+NO_PARALLEL(t1, t2)*/ * FROM t1, t2;
Aucune analyse parallèle n'est effectuée sur t1 ni sur t2.
Désactiver les sous-requêtes parallèles
SELECT /*+NO_PARALLEL(@subq1)*/ SUM(t.a) FROM t WHERE t.a =
(SELECT /*+QB_NAME(subq1)*/ SUM(t1.a) FROM t1);
SELECT SUM(t.a) FROM t WHERE t.a =
(SELECT /*+NO_PARALLEL()*/ SUM(t1.a) FROM t1);
Ces deux instructions bloquent l'exécution parallèle pour la sous-requête concernée.
PQ_DISTRIBUTE (opérations de jointure)
Ce hint contrôle la répartition des données lors des jointures parallèles. Il gère aussi bien la distribution d'une table unique que celle impliquant deux tables jointes.
Syntaxe
Distribution sur table unique :
/*+ PQ_DISTRIBUTE([query_block] table_name strategy) */
Distribution de jointure à deux tables — définit le mode de jointure entre table_name et la table précédente :
/*+ PQ_DISTRIBUTE([query_block] table_name strategy1 [strategy2]) */
Si seule strategy1 est présente, la distribution s'applique à table_name. Lorsque strategy1 et strategy2 sont toutes deux spécifiées, elles déterminent conjointement la distribution de la jointure entre table_name et la table précédente.
La « table précédente » peut être une table physique ou une table intermédiaire issue d'une opération de jointure antérieure.
Paramètres
| Paramètre | Description |
|---|---|
query_block |
Identifiant du bloc de requête ciblé par le hint. |
table_name |
Table à laquelle s'applique la stratégie de distribution. |
strategy |
Méthode de distribution employée. Consultez les valeurs valides ci-dessous. |
Valeurs de stratégie
| Stratégie | Description |
|---|---|
PQ_GATHER |
Centralise les données vers un worker de la phase précédente. |
PQ_HASH |
Mélange et répartit les données entre plusieurs workers de la phase précédente. |
PQ_BROADCAST |
Diffuse les données vers l'ensemble des workers de la phase précédente. |
PQ_NONE |
Aucune distribution de données n'est effectuée. |
Exemples
Distribution sur table unique
SELECT /*+ PARALLEL(t1) PQ_DISTRIBUTE(t1 PQ_GATHER) */ * FROM t AS t1;
La table t1 est analysée en parallèle. Le leader collecte ensuite les résultats sans redistribution supplémentaire.
SELECT /*+ PARALLEL(t1) PQ_DISTRIBUTE(t1 PQ_HASH) */ t1.a, SUM(t1.b) FROM t AS t1 GROUP BY t1.a;
Après une analyse parallèle de t1, les données sont distribuées par hachage aux workers de la phase suivante selon la clé de regroupement.
Distribution de jointure à deux tables
SELECT /*+ PARALLEL(t1) PARALLEL(t2) PQ_DISTRIBUTE(t2 PQ_HASH PQ_HASH) */ *
FROM t AS t1 STRAIGHT_JOIN t AS t2 ON t1.b = t2.c;
Les deux tables subissent une analyse parallèle suivie d'une distribution par hachage vers les workers de la phase suivante, permettant une jointure colocalisée. Le leader rassemble enfin les résultats définitifs.
SELECT /*+ PARALLEL(t1) PARALLEL(t2) PQ_DISTRIBUTE(t2 PQ_GATHER PQ_GATHER) */ *
FROM t AS t1 STRAIGHT_JOIN t AS t2 ON t1.b = t2.c;
Suite à l'analyse parallèle des deux tables, le leader récupère l'ensemble des données pour réaliser lui-même la jointure.
Stratégies conflictuelles
SELECT /*+ PARALLEL(t1) PARALLEL(t2) PQ_DISTRIBUTE(t2 PQ_HASH PQ_GATHER) */ *
FROM t AS t1 STRAIGHT_JOIN t AS t2 ON t1.b = t2.c;
En raison d'un conflit entre les stratégies (PQ_HASH pour t1 contre PQ_GATHER pour t2), aucun plan de requête parallèle ne peut être généré.
PQ_GROUPBY (agrégation GROUP BY)
Ce hint détermine le mode d'exécution parallèle appliqué aux agrégations GROUP BY.
Syntaxe
/*+ PQ_GROUPBY(strategy) */
Valeurs de stratégie
| Stratégie | Description |
|---|---|
PQ_ONEPHASE |
Répartit les données entre les workers selon la clé de groupe. Chaque worker effectue l'agrégation en parallèle. |
PQ_TWOPHASE_GATHER |
Les workers réalisent des agrégations partielles indépendantes. Le leader fusionne ensuite ces résultats partiels pour obtenir le résultat final. |
PQ_TWOPHASE_HASH |
Après une première agrégation locale par chaque worker, les données sont redistribuées par clé de groupe aux workers de la phase suivante pour l'agrégation finale. |
PQ_SERIAL |
L'agrégation GROUP BY s'effectue de manière séquentielle. |
Exemples
SELECT /*+ PARALLEL(t1) PQ_GROUPBY(PQ_ONEPHASE) */ t1.a, SUM(t1.b) FROM t AS t1 GROUP BY t1.a;
La table t1 est analysée en parallèle, puis les données sont distribuées aux workers suivants selon la colonne t1.a. Les workers agrègent les données simultanément avant que le leader ne collecte les résultats.
SELECT /*+ PARALLEL(t1) PQ_GROUPBY(PQ_TWOPHASE_HASH) */ t1.a, SUM(t1.b) FROM t AS t1 GROUP BY t1.a;
Les workers analysent t1 en parallèle et procèdent à une agrégation locale. Les résultats intermédiaires sont ensuite redistribués selon t1.a pour l'agrégation finale, dont le leader assure la collecte.
PQ_DISTINCT (agrégation DISTINCT)
Utilisez ce hint pour piloter le mode d'exécution parallèle des opérations DISTINCT.
Syntaxe
/*+ PQ_DISTINCT(strategy) */
Valeurs de stratégie
| Stratégie | Description |
|---|---|
PQ_TWOPHASE_GATHER |
Chaque worker traite une agrégation partielle. Le leader assemble ensuite ces résultats pour former le résultat final. |
PQ_SERIAL |
Le traitement DISTINCT s'opère de façon séquentielle. |
PQ_WINDOW (fonctions de fenêtrage)
Ce paramètre régit le mode d'exécution parallèle dédié aux fonctions de fenêtrage.
Syntaxe
/*+ PQ_WINDOW([window_name] strategy) */
Un hint ciblant explicitement un window_name prévaut toujours sur un hint générique sans nom de fenêtre.
Paramètres
| Paramètre | Description |
|---|---|
window_name |
Fonction de fenêtrage visée par la stratégie. En son absence, la stratégie s'applique à toutes les fonctions de fenêtrage. |
strategy |
Mode d'exécution souhaité. Reportez-vous aux valeurs valides ci-après. |
Valeurs de stratégie
| Stratégie | Description |
|---|---|
PQ_ONEPHASE |
Les données sont partitionnées selon la clause PARTITION BY. Les workers calculent la fonction de fenêtrage en parallèle. |
PQ_SERIAL |
Le calcul de la fonction de fenêtrage s'effectue séquentiellement. |
Exemple
SELECT /*+ PQ_WINDOW(PQ_ONEPHASE) PQ_WINDOW(win PQ_SERIAL) */
ROW_NUMBER() OVER(win) AS 'row_number',
RANK() OVER(PARTITION BY name ORDER BY salary DESC)
FROM employee_salaries WINDOW win AS (PARTITION BY dept ORDER BY salary DESC);
La fenêtre nommée win est traitée de manière séquentielle. Toutes les autres fonctions de fenêtrage sont réparties entre les workers selon la clé PARTITION BY pour un calcul parallèle.
PQ_ORDERBY (tri)
Définissez le mode d'exécution parallèle pour les opérations de tri ORDER BY.
Syntaxe
/*+ PQ_ORDERBY(strategy) */
Valeurs de stratégie
| Stratégie | Description |
|---|---|
PQ_TWOPHASE_GATHER |
Les workers trient les données en parallèle. Le leader fusionne ensuite les résultats partiels pour produire le classement final. |
PQ_SERIAL |
Le tri est réalisé de manière séquentielle. |
PQ_PUSHDOWN et NO_PQ_PUSHDOWN (sous-requêtes parallèles)
Ces hints contrôlent la politique d'exécution parallèle des sous-requêtes. Pour plus de détails sur la prise en charge des sous-requêtes, consultez la rubrique Consulter les plans d'exécution des requêtes parallèles.
Syntaxe
/*+ PQ_PUSHDOWN [( [query_block])] */ -- Pushdown policy
/*+ NO_PQ_PUSHDOWN [( [query_block])] */ -- Shared access policy
Exemples
Politique de pushdown :
EXPLAIN SELECT /*+ PQ_PUSHDOWN(@qb1) */ * FROM t2 WHERE t2.a =
(SELECT /*+ QB_NAME(qb1) */ a FROM t1);
Politique d'accès partagé :
EXPLAIN SELECT /*+ NO_PQ_PUSHDOWN(@qb1) */ * FROM t2 WHERE t2.a =
(SELECT /*+ QB_NAME(qb1) */ a FROM t1);
Hint inline sans référence à un bloc de requête :
EXPLAIN SELECT * FROM t2 WHERE t2.a =
(SELECT /*+ NO_PQ_PUSHDOWN() */ a FROM t1);