Tous les produits
Search
Centre de documentation

PolarDB:Utiliser Hybrid Plan pour accélérer les requêtes sur tables larges

Dernière mise à jour :Aug 11, 2026

Les requêtes sur tables larges qui filtrent sur quelques colonnes tout en récupérant l'ensemble des colonnes engendrent un problème d'amplification des lectures. Un index columnstore gère efficacement le filtrage, mais la récupération de chaque colonne projetée via cet index s'avère coûteuse. Un index row store évite cette amplification, mais perd la vitesse de filtrage colonnaire. Hybrid Plan combine ces deux types d'index au sein d'une même exécution de requête afin de tirer parti des avantages de chacun.

image.png

Fonctionnement

Hybrid Plan divise l'exécution en deux étapes :

  1. L'optimiseur utilise l'In-Memory Column Index (IMCI) pour filtrer les lignes et récupérer leurs clés primaires.

  2. Le système exploite ces clés primaires pour rechercher les données complètes des lignes dans l'index primaire InnoDB.

Cette approche élimine l'amplification des lectures : IMCI effectue le balayage colonnaire rapide, tandis qu'InnoDB retourne uniquement les lignes correspondantes dans leur intégralité.

Applicabilité

  • Édition du cluster : PolarDB for MySQL Enterprise Edition

  • Versions prises en charge :

    • PolarDB for MySQL 8.0.1, révision 8.0.1.1.37 ou ultérieure

    • PolarDB for MySQL 8.0.2, révision 8.0.2.2.23.1 ou ultérieure

Cas d'utilisation

Requêtes sur tables larges retournant au moins 15 colonnes.

Limitations

Les tables fournissant des colonnes de sortie pour la requête doivent posséder une clé primaire explicitement définie.

Remarque

Si Hybrid Plan ne parvient pas à accélérer une instruction SQL lente en raison de limitations telles que le type de table, contactez-nous pour obtenir de l'aide.

Paramètres

Deux paramètres régissent Hybrid Plan. Ils opèrent à différents niveaux et respectent un ordre de priorité clair :

  1. imci_enable_hybrid_plan — contrôle la fonctionnalité de manière globale. Défini sur ON, ce paramètre permet à l'optimiseur d'évaluer chaque requête et d'appliquer automatiquement Hybrid Plan si le coût d'exécution estimé est réduit.

  2. imci_optimizer_switch — indice par requête. Spécifier force_hybrid_index_search=ON dans un indice force l'utilisation de Hybrid Plan pour cette instruction, indépendamment de l'estimation de coût de l'optimiseur.

Priorité : Un indice par requête (force_hybrid_index_search=ON) prévaut sur la décision automatique de l'optimiseur. Ce dernier ne prend une décision qu'en l'absence d'indice et lorsque imci_enable_hybrid_plan est activé (ON).

Paramètre Valeur par défaut Description
imci_enable_hybrid_plan ON Active Hybrid Plan globalement. Définissez ce paramètre sur OFF pour désactiver la fonctionnalité.
imci_optimizer_switch force_hybrid_index_search=OFF Substitution par requête. Spécifiez force_hybrid_index_search=ON dans un indice pour imposer Hybrid Plan à une instruction spécifique.

Activer et vérifier Hybrid Plan

Cette section prend SELECT * FROM t1; comme exemple.

Étape 1 : Se connecter au cluster

Connectez-vous au cluster PolarDB. Pour plus de détails, consultez Se connecter à un cluster de base de données.

Étape 2 : Activer la fonctionnalité

Définissez imci_enable_hybrid_plan sur ON. L'optimiseur applique alors automatiquement Hybrid Plan aux requêtes sur tables larges éligibles.

SET imci_enable_hybrid_plan=ON;

Étape 3 : Forcer l'utilisation de Hybrid Plan pour une requête spécifique (facultatif)

Si l'optimiseur ne sélectionne pas Hybrid Plan pour une requête (par exemple, si son estimation de coût favorise un autre plan), ajoutez un indice pour outrepasser cette décision :

SELECT /*+ SET_VAR(imci_optimizer_switch='force_hybrid_index_search=ON') */ * FROM t1;

Étape 4 : Vérifier que Hybrid Plan est actif

Exécutez EXPLAIN sur la requête pour confirmer l'utilisation de Hybrid Plan. Lorsqu'il est actif, le plan d'exécution inclut l'opérateur HybridIndexSearch.

EXPLAIN SELECT /*+ SET_VAR(imci_optimizer_switch='force_hybrid_index_search=ON') */ * FROM t1;

Sortie attendue :

+----+-------------------------+------+---------------------------------------------------------------+
| ID | Operator                | Name | Extra Info                                                    |
+----+-------------------------+------+---------------------------------------------------------------+
|  1 | Select Statement        |      | IMCI Execution Plan (max_dop = 32, max_query_mem = unlimited) |
|  2 | └─HybridIndexSearch     |      | Used table: t1                                                |
|  3 |   └─Compute Scalar      |      |                                                               |
|  4 |     └─Table Scan        | t1   |                                                               |
+----+-------------------------+------+---------------------------------------------------------------+
4 rows in set (0.02 sec)

L'opérateur HybridIndexSearch à la ligne 2 confirme que Hybrid Plan est actif. La ligne 1 affiche le contexte d'exécution IMCI ; la ligne 4 confirme le balayage de la table InnoDB pour la récupération complète des lignes.

Test de performance

Le test suivant utilise le jeu de données OnTime de ClickHouse. La table OnTime comporte 109 colonnes, ce qui en fait une table large représentative. Le schéma de la table a été modifié pour inclure une clé primaire explicite. Le schéma modifié est le suivant :

CREATE TABLE `ontime` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Year` year(4) DEFAULT NULL,
  `Quarter` tinyint(4) DEFAULT NULL,
  `Month` tinyint(4) DEFAULT NULL,
  `DayofMonth` tinyint(4) DEFAULT NULL,
  `DayOfWeek` tinyint(4) DEFAULT NULL,
  `FlightDate` date DEFAULT NULL,
  `UniqueCarrier` char(7) DEFAULT NULL,
  `AirlineID` int(11) DEFAULT NULL,
  `Carrier` char(2) DEFAULT NULL,
  `TailNum` varchar(50) DEFAULT NULL,
  `FlightNum` varchar(10) DEFAULT NULL,
  `OriginAirportID` int(11) DEFAULT NULL,
  `OriginAirportSeqID` int(11) DEFAULT NULL,
  `OriginCityMarketID` int(11) DEFAULT NULL,
  `Origin` char(5) DEFAULT NULL,
  `OriginCityName` varchar(100) DEFAULT NULL,
  `OriginState` char(2) DEFAULT NULL,
  `OriginStateFips` varchar(10) DEFAULT NULL,
  `OriginStateName` varchar(100) DEFAULT NULL,
  `OriginWac` int(11) DEFAULT NULL,
  `DestAirportID` int(11) DEFAULT NULL,
  `DestAirportSeqID` int(11) DEFAULT NULL,
  `DestCityMarketID` int(11) DEFAULT NULL,
  `Dest` char(5) DEFAULT NULL,
  `DestCityName` varchar(100) DEFAULT NULL,
  `DestState` char(2) DEFAULT NULL,
  `DestStateFips` varchar(10) DEFAULT NULL,
  `DestStateName` varchar(100) DEFAULT NULL,
  `DestWac` int(11) DEFAULT NULL,
  `CRSDepTime` int(11) DEFAULT NULL,
  `DepTime` int(11) DEFAULT NULL,
  `DepDelay` int(11) DEFAULT NULL,
  `DepDelayMinutes` int(11) DEFAULT NULL,
  `DepDel15` int(11) DEFAULT NULL,
  `DepartureDelayGroups` int(11) DEFAULT NULL,
  `DepTimeBlk` varchar(20) DEFAULT NULL,
  `TaxiOut` int(11) DEFAULT NULL,
  `WheelsOff` int(11) DEFAULT NULL,
  `WheelsOn` int(11) DEFAULT NULL,
  `TaxiIn` int(11) DEFAULT NULL,
  `CRSArrTime` int(11) DEFAULT NULL,
  `ArrTime` int(11) DEFAULT NULL,
  `ArrDelay` int(11) DEFAULT NULL,
  `ArrDelayMinutes` int(11) DEFAULT NULL,
  `ArrDel15` int(11) DEFAULT NULL,
  `ArrivalDelayGroups` int(11) DEFAULT NULL,
  `ArrTimeBlk` varchar(20) DEFAULT NULL,
  `Cancelled` tinyint(4) DEFAULT NULL,
  `CancellationCode` char(1) DEFAULT NULL,
  `Diverted` tinyint(4) DEFAULT NULL,
  `CRSElapsedTime` int(11) DEFAULT NULL,
  `ActualElapsedTime` int(11) DEFAULT NULL,
  `AirTime` int(11) DEFAULT NULL,
  `Flights` int(11) DEFAULT NULL,
  `Distance` int(11) DEFAULT NULL,
  `DistanceGroup` tinyint(4) DEFAULT NULL,
  `CarrierDelay` int(11) DEFAULT NULL,
  `WeatherDelay` int(11) DEFAULT NULL,
  `NASDelay` int(11) DEFAULT NULL,
  `SecurityDelay` int(11) DEFAULT NULL,
  `LateAircraftDelay` int(11) DEFAULT NULL,
  `FirstDepTime` varchar(10) DEFAULT NULL,
  `TotalAddGTime` varchar(10) DEFAULT NULL,
  `LongestAddGTime` varchar(10) DEFAULT NULL,
  `DivAirportLandings` varchar(10) DEFAULT NULL,
  `DivReachedDest` varchar(10) DEFAULT NULL,
  `DivActualElapsedTime` varchar(10) DEFAULT NULL,
  `DivArrDelay` varchar(10) DEFAULT NULL,
  `DivDistance` varchar(10) DEFAULT NULL,
  `Div1Airport` varchar(10) DEFAULT NULL,
  `Div1AirportID` int(11) DEFAULT NULL,
  `Div1AirportSeqID` int(11) DEFAULT NULL,
  `Div1WheelsOn` varchar(10) DEFAULT NULL,
  `Div1TotalGTime` varchar(10) DEFAULT NULL,
  `Div1LongestGTime` varchar(10) DEFAULT NULL,
  `Div1WheelsOff` varchar(10) DEFAULT NULL,
  `Div1TailNum` varchar(10) DEFAULT NULL,
  `Div2Airport` varchar(10) DEFAULT NULL,
  `Div2AirportID` int(11) DEFAULT NULL,
  `Div2AirportSeqID` int(11) DEFAULT NULL,
  `Div2WheelsOn` varchar(10) DEFAULT NULL,
  `Div2TotalGTime` varchar(10) DEFAULT NULL,
  `Div2LongestGTime` varchar(10) DEFAULT NULL,
  `Div2WheelsOff` varchar(10) DEFAULT NULL,
  `Div2TailNum` varchar(10) DEFAULT NULL,
  `Div3Airport` varchar(10) DEFAULT NULL,
  `Div3AirportID` int(11) DEFAULT NULL,
  `Div3AirportSeqID` int(11) DEFAULT NULL,
  `Div3WheelsOn` varchar(10) DEFAULT NULL,
  `Div3TotalGTime` varchar(10) DEFAULT NULL,
  `Div3LongestGTime` varchar(10) DEFAULT NULL,
  `Div3WheelsOff` varchar(10) DEFAULT NULL,
  `Div3TailNum` varchar(10) DEFAULT NULL,
  `Div4Airport` varchar(10) DEFAULT NULL,
  `Div4AirportID` int(11) DEFAULT NULL,
  `Div4AirportSeqID` int(11) DEFAULT NULL,
  `Div4WheelsOn` varchar(10) DEFAULT NULL,
  `Div4TotalGTime` varchar(10) DEFAULT NULL,
  `Div4LongestGTime` varchar(10) DEFAULT NULL,
  `Div4WheelsOff` varchar(10) DEFAULT NULL,
  `Div4TailNum` varchar(10) DEFAULT NULL,
  `Div5Airport` varchar(10) DEFAULT NULL,
  `Div5AirportID` int(11) DEFAULT NULL,
  `Div5AirportSeqID` int(11) DEFAULT NULL,
  `Div5WheelsOn` varchar(10) DEFAULT NULL,
  `Div5TotalGTime` varchar(10) DEFAULT NULL,
  `Div5LongestGTime` varchar(10) DEFAULT NULL,
  `Div5WheelsOff` varchar(10) DEFAULT NULL,
  `Div5TailNum` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=58592318 DEFAULT CHARSET=latin1 COMMENT='columnar=1'

Requête de test :

SELECT * FROM ontime ORDER BY ArrTime LIMIT 1000;

Toutes les requêtes ont été exécutées à froid.

Stratégie d'exécution Temps de requête
Row store uniquement 232,48 secondes
Index columnstore (IMCI) uniquement 2,56 secondes
Hybrid Plan 0,33 seconde

Pour cette charge de travail, Hybrid Plan est 7,8 fois plus rapide que l'index columnstore seul et 704 fois plus rapide que le row store seul.