Todos os produtos
Search
Central de documentação

PolarDB:Eliminar GROUP BY/ORDER BY redundante

Última atualização: Jun 29, 2026

Cláusulas GROUP BY ou ORDER BY redundantes forçam o banco de dados a executar operações desnecessárias de ordenação ou hash, consumindo recursos significativos de CPU e memória. Essa sobrecarga é especialmente custosa para consultas de processamento analítico (AP) em grandes conjuntos de dados. O PolarDB for MySQL detecta e remove automaticamente essas operações redundantes por meio da análise de dependência funcional (FD), proporcionando um desempenho de consulta até 29% mais rápido nos benchmarks TPC-H, sem exigir alterações no código da aplicação.

Escopo

  • Série do produto: Cluster Edition, Standard Edition

  • Versão: MySQL 8.0.2, revisão 8.0.2.2.33 ou posterior

Ative o recurso

Dois parâmetros controlam essa otimização:

Parâmetro

Nível

Padrão

Valores válidos

loose_groupby_elimination_mode

Global/Sessão

REPLICA_ON

REPLICA_ON, ON, OFF

loose_orderby_elimination_mode

Global/Sessão

REPLICA_ON

REPLICA_ON, ON, OFF

Valores válidos:

  • REPLICA_ON (padrão): ativa o recurso apenas em nós somente leitura (RO).

  • ON: ativa o recurso em todos os nós.

  • OFF: desativado.

Nomenclatura dos parâmetros por interface:

  • Console do PolarDB: os parâmetros incluem o prefixo loose_ para garantir compatibilidade com arquivos de configuração do MySQL. Localize e modifique loose_groupby_elimination_mode e loose_orderby_elimination_mode.

  • Sessão de banco de dados (com o comando SET): remova o prefixo loose_ e utilize o nome original do parâmetro — groupby_elimination_mode e orderby_elimination_mode.

Como funciona

O otimizador elimina cláusulas GROUP BY e ORDER BY redundantes ao inferir dependências funcionais (FDs) a partir dos metadados das tabelas e das condições da consulta.

O que é uma dependência funcional?

Se a coluna A determina unicamente a coluna B, então B depende funcionalmente de A — representado como A -> B. Por exemplo, em uma tabela de usuários onde user_id é a chave primária, a relação user_id -> nickname é válida, pois cada user_id corresponde a exatamente um nickname.

Fontes de dependência funcional:

Source

Exemplo

Chaves primárias e chaves únicas

user_id (chave primária) determina todas as outras colunas da linha

Condições de equi-join

t1.pk = t2.fk propaga a unicidade de t1.pk para t2

Condições de filtro constante

WHERE status = 'active' torna status uma constante no resultado

Regras de otimização:

Regra

Condição

Resultado

Eliminação de GROUP BY

As colunas do GROUP BY incluem uma chave primária ou identificam unicamente cada linha

Remoção de toda a cláusula GROUP BY

Eliminação de GROUP BY (constantes)

Todas as colunas do GROUP BY são constantes

Remoção do GROUP BY e adição de LIMIT 1

Eliminação de ORDER BY

Todas as colunas do ORDER BY são constantes

Remoção de toda a cláusula ORDER BY

Simplificação de GROUP BY/ORDER BY

Existe FD entre as colunas da cláusula (ex.: GROUP BY x, y onde x -> y)

Simplificação da cláusula (ex.: para GROUP BY x)

Cenários de otimização

Cenário 1: Agrupamento por chave primária ou única

Condições de acionamento:

  • A cláusula GROUP BY inclui a chave primária de uma tabela.

  • As demais colunas na lista do GROUP BY são determinadas funcionalmente por essa chave.

Cenário de negócio: calcular a contagem total de pedidos por usuário e exibir o nome de usuário correspondente.

SQL original:

-- user_id is the primary key of the user table and uniquely determines user_name.
SELECT
    u.user_id,
    u.user_name,
    COUNT(o.order_id)
FROM user u
JOIN orders o ON u.user_id = o.user_id
GROUP BY
    u.user_id,
    u.user_name;

Ação do otimizador: como user_id é a chave primária, a FD user_id -> user_name se aplica. O otimizador simplifica GROUP BY u.user_id, u.user_name para GROUP BY u.user_id, eliminando o agrupamento redundante em user_name.

SQL otimizado:

SELECT
    u.user_id,
    u.user_name,
    COUNT(o.order_id)
FROM user u
JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id;

Verifique a otimização:

SHOW WARNINGS;

A coluna Message exibe a consulta reescrita apenas com GROUP BY u.user_id, confirmando a remoção de u.user_name da chave de agrupamento.

Cenário 2: Agrupamento por constantes

Condições de acionamento:

  • Todas as colunas da cláusula GROUP BY aparecem como constantes de igualdade na cláusula WHERE.

Cenário de negócio: consultar uma linha específica com base em valores exatos de colunas.

SQL original:

SELECT a, b FROM t1 WHERE a = 1 AND b = 1 GROUP BY a, b;

Ação do otimizador: tanto a quanto b são constantes na cláusula WHERE, portanto o conjunto de resultados contém no máximo uma linha. O otimizador remove o GROUP BY e adiciona LIMIT 1.

SQL otimizado:

SELECT a, b FROM t1 WHERE a = 1 AND b = 1 LIMIT 1;

Verifique a otimização:

SHOW WARNINGS;

A coluna Message mostra a consulta reescrita com LIMIT 1 e sem a cláusula GROUP BY.

Cenário 3: Junção de múltiplas tabelas com agrupamento complexo (TPC-H Q10)

Condições de acionamento:

  • Uma junção de múltiplas tabelas propaga a FD de uma chave primária por meio de condições de equi-join.

  • Todas as colunas não chave na lista do GROUP BY são determinadas transitivamente pela chave primária.

SQL original (TPC-H Q10):

SELECT
    c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment,
    SUM(l_extendedprice * (1 - l_discount)) AS revenue
FROM customer, orders, lineitem, nation
WHERE c_custkey = o_custkey
  AND l_orderkey = o_orderkey
  AND c_nationkey = n_nationkey
  -- Other filter conditions...
GROUP BY
    c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment
ORDER BY revenue DESC
LIMIT 20;

Ação do otimizador:

  1. Dependência de chave primária: c_custkey é a chave primária da tabela customer, logo determina c_name, c_acctbal, c_phone, c_address, c_comment e c_nationkey.

  2. Propagação de dependência: a condição de junção c_nationkey = n_nationkey e o fato de n_nationkey ser a chave primária de nation significam que c_custkey também determina n_name.

  3. Simplificação: todas as colunas não chave na lista do GROUP BY dependem funcionalmente de c_custkey. O otimizador simplifica a cláusula para GROUP BY c_custkey.

SQL otimizado:

SELECT
    c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment,
    SUM(l_extendedprice * (1 - l_discount)) AS revenue
FROM customer, orders, lineitem, nation
WHERE c_custkey = o_custkey
  AND l_orderkey = o_orderkey
  AND c_nationkey = n_nationkey
  -- Other filter conditions...
GROUP BY c_custkey
ORDER BY revenue DESC
LIMIT 20;

Verifique a otimização:

SHOW WARNINGS;

A coluna Message apresenta a consulta reescrita apenas com GROUP BY c_custkey, confirmando a remoção de todas as outras colunas da chave de agrupamento.

Cenário 4: Simplificação de ORDER BY com coluna computada

Condições de acionamento:

  • A cláusula ORDER BY inclui uma coluna que é uma função determinística de outras colunas presentes na mesma cláusula.

  • Essa coluna está definida como UNIQUE NOT NULL.

Esquema da tabela:

CREATE TABLE t1 (
  a INT,
  b INT,
  c INT AS (a + b) UNIQUE NOT NULL
);

SQL original:

EXPLAIN SELECT a, b FROM t1 ORDER BY a, b, c;

Ação do otimizador: a coluna c é calculada a partir de a e b (c = a + b) e definida como UNIQUE NOT NULL, estabelecendo a FD (a, b) -> c. O otimizador simplifica ORDER BY a, b, c para ORDER BY a, b.

Verifique a otimização:

SHOW WARNINGS;
+-------+------+-------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                       |
+-------+------+-------------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` order by `test`.`t1`.`a`,`test`.`t1`.`b` |
+-------+------+-------------------------------------------------------------------------------------------------------------------------------+

A consulta reescrita na coluna Message confirma a remoção de c da chave de ordenação.

Benchmark de desempenho

Testes realizados em um conjunto de dados padrão TPC-H de 100 GB demonstram que ativar a eliminação de GROUP BY melhora significativamente o desempenho da consulta Q10.

Cenário de teste

Com eliminação

Sem eliminação

Melhoria

In-Memory Column Index (IMCI) com 1 DOP (dentro de 1 dia da geração dos dados)

48 segundos

68 segundos

29%

In-Memory Column Index (IMCI) com 32 DOP (dentro de 32 dias da geração dos dados)

1,9 segundos

2,6 segundos

27%

A implementação do TPC-H descrita aqui baseia-se na metodologia de benchmarking TPC-H e não pode ser comparada aos resultados oficiais publicados do TPC-H. Estes testes não atendem integralmente a todos os requisitos do TPC-H. As melhorias reais de desempenho podem variar conforme a complexidade da consulta, a distribuição dos dados e as especificações do cluster.