Todos os produtos
Search
Central de documentação

PolarDB:Gerenciamento de planos de execução

Última atualização: Jul 14, 2026

O PolarDB-X armazena em cache planos de execução de instruções SQL parametrizadas para manter a estabilidade do desempenho de consultas complexas durante atualizações de versão. Esse mecanismo consiste em duas camadas: plan cache e SQL Plan Management (SPM).

Como funciona

Ao receber uma instrução SQL, o PolarDB-X a processa na seguinte ordem:

  1. Parametrização: Substitui todos os valores constantes da instrução pelo caractere de espaço reservado (?).

  2. Verificação do plan cache: Usa o SQL parametrizado como chave para buscar um plano de execução em cache. Se não houver plano armazenado, aciona o otimizador para gerar um novo.

  3. Roteamento de instruções simples: Executa diretamente as instruções simples. O gerenciamento de planos de execução aplica-se apenas a instruções complexas.

  4. Seleção do melhor plano para instruções complexas: Executa a instrução com o plano de execução fixo armazenado na baseline. Se houver múltiplos planos na baseline, o Plan Enumerator selecione aquele com o menor custo.

Plan cache

O plan cache vem ativado por padrão no PolarDB-X. Após a parametrização, o PolarDB-X substitui todas as constantes de uma instrução SQL por ? e cria uma lista de parâmetros. No plano de execução, o SQL dentro do operador LogicalView contém esses espaços reservados ?.

Execute EXPLAIN em qualquer instrução para verifique se ela atinge o plan cache. O campo HitCache na saída indica o resultado:

EXPLAIN SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

A saída inclui um indicador HitCache:true ou HitCache:false.

Gerenciamento de planos de execução

Depois que uma instrução SQL complexa passa pelo plan cache, o SQL Plan Management (SPM) aplica o gerenciamento de planos de execução sobre ela.

Tanto o plan cache quanto o gerenciamento de planos de execução usam a instrução SQL parametrizada como chave de busca. O plan cache abrange todas as instruções SQL; já o gerenciamento de planos de execução aplica-se somente a consultas complexas.

Cada instrução SQL mapeia exatamente para uma baseline. Uma baseline contém um ou mais planos de execução. O SPM avalia o custo de cada plano com base nos valores atuais dos parâmetros e selecione o plano de menor custo. Quando um plano de execução do plan cache entra no SPM:

  • Se o plano for conhecido, o SPM verifique se ele possui o menor custo.

  • Se o plano for desconhecido, o SPM o avalia para determinar se há necessidade de otimização.

Durante a evolução automática de planos, o SPM adiciona automaticamente à baseline os melhores planos descobertos pelo Plan Enumerator.

Comandos BASELINE

O PolarDB-X fornece a família de comandos BASELINE para gerencie planos de execução.

Sintaxe:

BASELINE (LOAD|PERSIST|CLEAR|VALIDATE|LIST|DELETE) [Signed Integer, Signed Integer, ...]
BASELINE (ADD|FIX) SQL (HINT Select Statement)

Referência de comandos:

Comando

Descrição

BASELINE ADD SQL <hint> <select>

Adiciona à baseline um plano de execução gerado com uma hint. Tanto o novo plano quanto os existentes permanecem disponíveis; o Plan Enumerator selecione o de menor custo em tempo de execução.

BASELINE FIX SQL <hint> <select>

Fixa um plano de execução como obrigatório. O PolarDB-X sempre usa esse plano, independentemente dos valores dos parâmetros.

BASELINE LIST

Lista todas as baselines e seus respectivos planos de execução.

BASELINE LOAD

Carrega a baseline especificada da tabela do sistema para a memória.

BASELINE LOAD_PLAN

Carrega o plano de execução especificado da tabela do sistema para a memória.

BASELINE PERSIST

Grava a baseline especificada em disco.

BASELINE PERSIST_PLAN

Grava o plano de execução especificado em disco.

BASELINE CLEAR

Remove a baseline especificada da memória.

BASELINE CLEAR_PLAN

Remove o plano de execução especificado da memória.

BASELINE DELETE

Exclua a baseline especificada do disco.

BASELINE DELETE_PLAN

Exclua o plano de execução especificado do disco.

Colunas de saída do BASELINE LIST:

Coluna

Descrição

BASELINE_ID

Identificador exclusivo da baseline, derivado do SQL parametrizado.

PARAMETERIZED_SQL

A instrução SQL após a substituição de todas as constantes por ?.

PLAN_ID

Identificador exclusivo do plano de execução dentro desta baseline.

EXTERNALIZED_PLAN

A árvore lógica do plano de execução serializada.

FIXED

1 se este plano estiver fixado via BASELINE FIX e for sempre selecionado, independentemente do custo. 0 se o plano participar da seleção baseada em custo.

ACCEPTED

1 se este plano estiver aceito e elegível para seleção pelo Plan Enumerator. 0 se o plano estiver pendente de verificação.

Uma baseline pode conter vários planos com ACCEPTED=1 . Quando nenhum plano tem FIXED=1 , o Plan Enumerator selecione o plano de menor custo em tempo de execução. Quando um plano tem FIXED=1 , o PolarDB-X sempre usa esse plano, ignorando o custo.

Otimizar planos de execução

Após alterações nos dados ou uma atualização do otimizador do PolarDB-X, pode existir um plano de execução melhor para uma consulta. Use BASELINE ADD e BASELINE FIX para introduzir e fixar planos melhores.

O exemplo a seguir mostra como alternar uma consulta Hash Join para um Batched Key Access join (BKA join) e fixar esse plano.

Etapa 1: Verifique o plano de execução atual

Execute EXPLAIN para visualizar o plano atual e confirme se ele atinge o plan cache.

EXPLAIN SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

Saída:

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| LOGICAL PLAN                                                                                                                                                                                                                                                                                                                                                   |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Gather(parallel=true)                                                                                                                                                                                                                                                                                                                                          |
|   ParallelHashJoin(condition="l_partkey = p_partkey", type="inner")                                                                                                                                                                                                                                                                                            |
|     LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true) |
|     LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)", parallel=true)                                                                                                                    |
| HitCache:true                                                                                                                                                                                                                                                                                                                                                  |
|                                                                                                                                                                                                                                                                                                                                                                |
|                                                                                                                                                                                                                                                                                                                                                                |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
7 rows in set (0.06 sec)

Execute BASELINE LIST para visualizar a baseline. Ela contém um plano (ParallelHashJoin), com FIXED=0 e ACCEPTED=1.

BASELINE LIST;

Saída:

+-------------+--------------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
| BASELINE_ID | PARAMETERIZED_SQL                                                              | PLAN_ID    | EXTERNALIZED_PLAN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | FIXED | ACCEPTED |
+-------------+--------------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
|  -399023558 | SELECT *
FROM lineitem
    JOIN part ON l_partkey = p_partkey
WHERE p_name LIKE ? | -935671684 |
Gather(parallel=true)
  ParallelHashJoin(condition="l_partkey = p_partkey", type="inner")
    LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true)
    LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)", parallel=true)
 |     0 |        1 |
+-------------+--------------------------------------------------------------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
1 row in set (0.02 sec)

Etapa 2: Validar o plano alternativo com uma hint

Use a hint /*+TDDL:BKA_JOIN(lineitem, part)*/ para gerar um plano BKA join sem modificar a baseline.

EXPLAIN /*+TDDL:bka_join(lineitem, part)*/ SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

Saída:

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| LOGICAL PLAN                                                                                                                                                                                                                                                                                                                                                   |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Gather(parallel=true)                                                                                                                                                                                                                                                                                                                                          |
|   ParallelBKAJoin(condition="l_partkey = p_partkey", type="inner")                                                                                                                                                                                                                                                                                             |
|     LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true) |
|     Gather(concurrent=true)                                                                                                                                                                                                                                                                                                                                    |
|       LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)")                                                                                                                                 |
| HitCache:false                                                                                                                                                                                                                                                                                                                                                 |
|                                                                                                                                                                                                                                                                                                                                                                |
|                                                                                                                                                                                                                                                                                                                                                                |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
8 rows in set (0.14 sec)

O valor HitCache:false confirme que o plano orientado por hint ainda não está na baseline. A baseline permanece inalterada.

Etapa 3: Adicionar o plano BKA join à baseline

Execute BASELINE ADD para adicionar o plano BKA join ao lado do plano Hash Join existente. O Plan Enumerator escolhe entre eles em tempo de execução com base no custo.

BASELINE ADD SQL /*+TDDL:bka_join(lineitem, part)*/ SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

Saída:

+-------------+--------+
| BASELINE_ID | STATUS |
+-------------+--------+
|  -399023558 | OK     |
+-------------+--------+
1 row in set (0.09 sec)

O comando BASELINE LIST agora exibe dois planos para o mesmo ID de baseline — o plano BKA join (PLAN_ID: -1024543942) e o plano Hash Join original (PLAN_ID: -935671684). Ambos possuem FIXED=0 e ACCEPTED=1.

BASELINE LIST;

Saída:

+-------------+--------------------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
| BASELINE_ID | PARAMETERIZED_SQL                                                              | PLAN_ID     | EXTERNALIZED_PLAN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | FIXED | ACCEPTED |
+-------------+--------------------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
|  -399023558 | SELECT *
FROM lineitem
    JOIN part ON l_partkey = p_partkey
WHERE p_name LIKE ? | -1024543942 |
Gather(parallel=true)
  ParallelBKAJoin(condition="l_partkey = p_partkey", type="inner")
    LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true)
    Gather(concurrent=true)
      LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)")
 |     0 |        1 |
|  -399023558 | SELECT *
FROM lineitem
    JOIN part ON l_partkey = p_partkey
WHERE p_name LIKE ? |  -935671684 |
Gather(parallel=true)
  ParallelHashJoin(condition="l_partkey = p_partkey", type="inner")
    LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true)
    LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)", parallel=true)
                   |     0 |        1 |
+-------------+--------------------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+----------+
2 rows in set (0.03 sec)

Conforme o valor de p_name LIKE ? muda, o PolarDB-X selecione dinamicamente diferentes planos de execução.

Etapa 4: Fixar o plano BKA join

Para usar sempre o plano BKA join, independentemente dos valores dos parâmetros, execute BASELINE FIX.

BASELINE FIX SQL /*+TDDL:bka_join(lineitem, part)*/ SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

Saída:

+-------------+--------+
| BASELINE_ID | STATUS |
+-------------+--------+
|  -399023558 | OK     |
+-------------+--------+
1 row in set (0.07 sec)

Após a fixação, o BASELINE LIST mostra o plano BKA join com FIXED=1 e o plano Hash Join com FIXED=0.

mysql> baseline list\G
*************************** 1. row ***************************
      BASELINE_ID: -399023558
PARAMETERIZED_SQL: SELECT *
FROM lineitem
    JOIN part ON l_partkey = p_partkey
WHERE p_name LIKE ?
          PLAN_ID: -1024543942
EXTERNALIZED_PLAN:
Gather(parallel=true)
  ParallelBKAJoin(condition="l_partkey = p_partkey", type="inner")
    LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true)
    Gather(concurrent=true)
      LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)")
            FIXED: 1
         ACCEPTED: 1
*************************** 2. row ***************************
      BASELINE_ID: -399023558
PARAMETERIZED_SQL: SELECT *
FROM lineitem
    JOIN part ON l_partkey = p_partkey
WHERE p_name LIKE ?
          PLAN_ID: -935671684
EXTERNALIZED_PLAN:
Gather(parallel=true)
  ParallelHashJoin(condition="l_partkey = p_partkey", type="inner")
    LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true)
    LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)", parallel=true)
            FIXED: 0
         ACCEPTED: 1
2 rows in set (0.01 sec)

Etapa 5: Verifique o plano fixado

Execute EXPLAIN novamente sem nenhuma hint.

EXPLAIN SELECT * FROM lineitem JOIN part ON l_partkey=p_partkey WHERE p_name LIKE '%green%';

Saída:

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| LOGICAL PLAN                                                                                                                                                                                                                                                                                                                                                   |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Gather(parallel=true)                                                                                                                                                                                                                                                                                                                                          |
|   ParallelBKAJoin(condition="l_partkey = p_partkey", type="inner")                                                                                                                                                                                                                                                                                             |
|     LogicalView(tables="[00-03].lineitem", shardCount=4, sql="SELECT `l_orderkey`, `l_partkey`, `l_suppkey`, `l_linenumber`, `l_quantity`, `l_extendedprice`, `l_discount`, `l_tax`, `l_returnflag`, `l_linestatus`, `l_shipdate`, `l_commitdate`, `l_receiptdate`, `l_shipinstruct`, `l_shipmode`, `l_comment` FROM `lineitem` AS `lineitem`", parallel=true) |
|     Gather(concurrent=true)                                                                                                                                                                                                                                                                                                                                    |
|       LogicalView(tables="[00-03].part", shardCount=4, sql="SELECT `p_partkey`, `p_name`, `p_mfgr`, `p_brand`, `p_type`, `p_size`, `p_container`, `p_retailprice`, `p_comment` FROM `part` AS `part` WHERE (`p_name` LIKE ?)")                                                                                                                                 |
| HitCache:true                                                                                                                                                                                                                                                                                                                                                  |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
8 rows in set (0.01 sec)

Os indicadores HitCache:true e ParallelBKAJoin confirme que o PolarDB-X agora usa sempre o plano BKA join fixado, sem necessidade de hint.