Em consultas agrupadas, o banco de dados aplica a cláusula HAVING após a agregação do GROUP BY. Isso significa que o sistema agrupa todas as linhas antes de descartar aquelas que falham no filtro. Se o filtro não depender da agregação, esse processamento será desnecessário.
O PolarDB transfere automaticamente condições de filtro elegíveis da cláusula HAVING para a cláusula WHERE e permite que o banco de dados filtre as linhas antes do agrupamento. Essa otimização reduz o volume de dados na etapa de agrupamento e melhora o desempenho da consulta.
Como funciona
O otimizador inspeciona a cláusula HAVING e identifica condições dependentes apenas das colunas do GROUP BY, e não de funções de agregação. Em seguida, reescreve a consulta para aplicar essas condições na cláusula WHERE antes do início do agrupamento. As condições restantes permanecem no HAVING.
Condições transferíveis
Uma condição é elegível quando depende exclusivamente das colunas na cláusula GROUP BY ou de colunas idênticas às colunas agrupadas.
Condições não transferíveis
Condições com referências a funções de agregação — como MAX(), SUM() ou COUNT() — não podem ser transferidas. Como os valores agregados só ficam disponíveis após o agrupamento, essas condições devem permanecer no HAVING.
Por exemplo, na consulta abaixo, não é possível transferir MAX(c) > 12 porque MAX(c) é uma agregação. Apenas t1.a > 2 é elegível:
SELECT t1.a, MAX(t1.b)
FROM t1
GROUP BY t1.a
HAVING (t1.a > 2) AND (MAX(c) > 12);
Após a transferência, a consulta fica assim:
SELECT t1.a, MAX(t1.b)
FROM t1
WHERE (t1.a > 2)
GROUP BY t1.a
HAVING (MAX(c) > 12);
Versões compatíveis
Este recurso requer uma das seguintes versões do mecanismo. Para verificar a versão do seu cluster, consulte Consultar a versão do mecanismo.
MySQL 8.0.1, versão de revisão 8.0.1.1.42 ou posterior
MySQL 8.0.2, versão de revisão 8.0.2.2.10 ou posterior
Configure a transferência de condições
Use os parâmetros a seguir para controlar a transferência de condições de HAVING para WHERE. Para obter detalhes sobre como definir parâmetros, consulte Configurar parâmetros de cluster e nó.
|
Parâmetro |
Escopo |
Descrição |
|
|
Global e sessão |
Ativa ou desativa a transferência de condições. Valores válidos: |
|
|
Global |
Define em quais nós a transferência de condições será executada. Valores válidos: |
**Valores de loose_having_cond_pushdown_mode**
|
Valor |
Comportamento |
|
|
Ativa a transferência de condições apenas em nós somente leitura. |
|
|
Ativa a transferência de condições em todos os nós. |
|
|
Desativa a transferência de condições em todos os nós. |
Exemplos
Exemplo 1: condição simples em uma coluna GROUP BY
A condição t1.a > 2 referencia apenas a coluna do GROUP BY, então o otimizador a move para a cláusula WHERE. A condição de agregação MAX(c) > 12 permanece no HAVING.
Antes da transferência:
SELECT t1.a, MAX(t1.b)
FROM t1
GROUP BY t1.a
HAVING (t1.a > 2) AND (MAX(c) > 12);
Após a transferência:
SELECT t1.a, MAX(t1.b)
FROM t1
WHERE (t1.a > 2)
GROUP BY t1.a
HAVING (MAX(c) > 12);
Exemplo 2: transferência parcial em uma condição composta
Quando uma condição composta mistura referências a colunas do GROUP BY com referências a colunas fora do GROUP BY, o otimizador extrai apenas as partes transferíveis. Neste caso, t1.a < 3 pode ser extraído da segunda ramificação OR e movido para WHERE.
Antes da transferência:
SELECT t1.a, MAX(t1.b), t1.c
FROM t1
GROUP BY t1.a
HAVING ((t1.a = t1.c) AND (t1.a > 1)) OR ((t1.a < 3) AND (t1.c > 3));
Após a transferência:
SELECT t1.a, MAX(t1.b), t1.c
FROM t1
WHERE ((t1.a = t1.c) AND (t1.a > 1)) OR (t1.a < 3)
GROUP BY t1.a
HAVING ((t1.a = t1.c) AND (t1.a > 1)) OR ((t1.a < 3) AND (t1.c > 3));
A cláusulaHAVINGoriginal completa é preservada para garantir resultados corretos. A cláusulaWHEREfiltra as linhas antes do agrupamento; já a cláusulaHAVINGexecuta a verificação final de integridade após o agrupamento.