Todos os produtos
Search
Central de documentação

Hologres:Otimize o desempenho de consultas em tabelas internas

Última atualização: Jul 15, 2026

Saiba como ajustar consultas em tabelas internas do Hologres mantendo estatísticas atualizadas, configurando shards, otimizando junções e agregações e projetando esquemas de tabela eficientes.

Guia rápido de decisão

Sintoma

Causa provável

Ação recomendada

Junções lentas em tabelas internas grandes

Estatísticas desatualizadas

Execute ANALYZE em todas as tabelas envolvidas na junção

Consultas verificam muitas linhas para filtros de intervalo ou igualdade

Ausência de clustering key, bitmap columns ou segment key

Adicione uma clustering_key para filtros de intervalo, bitmap_columns para filtros de igualdade ou uma segment_key para intervalos baseados em tempo

Alta latência em consultas pontuais

Tipo de armazenamento inadequado ou ausência de chave primária/índice

Use armazenamento híbrido ou por linha e defina uma chave primária e um índice apropriados

Agregações COUNT DISTINCT lentas

Deduplicação exata com alto consumo de recursos

Use APPROX_COUNT_DISTINCT ou UNIQ e considere usar a chave distinta como chave de distribuição

Agregações GROUP BY lentas

Redistribuição de dados e skew de dados nas chaves do GROUP BY

Defina as chaves do GROUP BY como chaves de distribuição sempre que possível e corrija o skew de dados

Mantenha as estatísticas

As Estatísticas (por exemplo, distribuições de dados, linhas, colunas) ajudam o otimizador a escolher planos de execução eficientes. Estatísticas desatualizadas podem causar seleção inadequada da ordem de junção e erros OOM.

Verifique se as estatísticas estão atualizadas

Execute EXPLAIN na consulta e verifique a estimativa de rows para cada tabela.

Se uma tabela grande mostrar rows=1000 (o valor padrão), as estatísticas estão desatualizadas.

Atualize as estatísticas

Execute ANALYZE nas tabelas com estatísticas obsoletas:

analyze <tablename>;

Identifique quando atualizar as estatísticas

Execute analyze <tablename> nas seguintes situações:

  • Após importar dados.

  • Após múltiplas operações INSERT, UPDATE ou DELETE.

  • Para tabelas internas e externas.

  • Nas tabelas pai de tabelas particionadas.

Caso encontre erros OOM durante junções ou consultas lentas, execute analyze <tablename> antes de importar os dados.

Configure a contagem de shards

A contagem de shards determina o paralelismo das consultas. Poucos shards limitam o paralelismo; muitos aumentam a sobrecarga de inicialização.

Entenda a contagem padrão de shards

O Hologres define uma contagem padrão de shards com base nas especificações da instância, aproximadamente igual às CUs de consulta disponíveis. Após o dimensionamento, os bancos de dados existentes mantêm sua contagem original de shards — apenas novos bancos de dados usam o padrão atualizado.

Determine quando ajustar a contagem de shards

  • Após aumentar a capacidade em 5 vezes ou mais: crie um novo Table Group com uma contagem maior de shards.

  • Para novas cargas de trabalho de negócios: crie um novo Table Group com a contagem adequada de shards.

  • Ao enfrentar problemas de paralelismo: verifique se o total de shards excede o padrão recomendado.

Nota

O total de shards em todos os Table Groups não deve exceder a contagem padrão de shards da instância para garantir a utilização ideal da CPU.

Otimize consultas JOIN

Utilize os métodos a seguir para melhorar o desempenho de junções.

Atualize estatísticas para consultas de junção

Conforme mencionado em Manter estatísticas, estatísticas desatualizadas podem fazer com que a tabela maior crie uma tabela hash, reduzindo a eficiência da junção. Execute ANALYZE para atualizar as estatísticas da tabela.

Selecione chaves de distribuição para junções locais

As chaves de distribuição determinam como os dados são distribuídos entre os shards. Uma seleção adequada permite junções locais e reduz a movimentação de dados.

Princípios para selecionar chaves de distribuição:

  • Use as colunas de junção como chave de distribuição.

  • Prefira colunas presentes em cláusulas GROUP BY frequentes.

  • Escolha colunas com distribuição de dados uniforme e discreta.

Exemplo: Ao unir tabelas frequentemente por uma coluna específica, defina essa coluna como chave de distribuição para ambas as tabelas:

-- Create tables with matching distribution keys
BEGIN;
CREATE TABLE orders (order_id INT, customer_id INT, amount DECIMAL);
CALL set_table_property('orders', 'distribution_key', 'customer_id');
COMMIT;

BEGIN;
CREATE TABLE customers (id INT, name TEXT);
CALL set_table_property('customers', 'distribution_key', 'id');
COMMIT;

Com as chaves de distribuição corretas, o plano de execução não mostra o operador Redistribute Motion, confirmando que as junções são locais.

Use Runtime Filter em junções

A partir da V2.0, o Hologres aplica automaticamente Acelerar junções de várias tabelas com runtime filters para junções entre tabelas grandes e pequenas, reduzindo os dados verificados sem necessidade de configuração manual.

Ajuste algoritmos de ordem de junção

Em consultas que unem muitas tabelas, o otimizador pode levar muito tempo para encontrar a ordem ideal de junção. Ajuste o algoritmo conforme necessário:

set optimizer_join_order = '<value>'; 

Algoritmo

Caso de uso

Compromisso

exhaustive2

Padrão para a maioria das consultas

Melhor plano, maior custo de otimização

greedy

Mais de 10 tabelas

Otimização mais rápida, plano potencialmente subótimo

query

SQL simples e bem ordenado

Executa na ordem do SQL, menor custo de otimização

Otimize operadores Motion em junções

O Hologres usa operadores Motion para redistribuir dados entre shards:

Tipo de Motion

Descrição

Redistribute Motion

Reorganiza os dados por hash ou aleatoriamente.

Broadcast Motion

Copia os dados para todos os shards.

Gather Motion

Coleta dados em um único shard.

Forward Motion

Transfere dados entre fontes externas e o Hologres para consultas federadas.

Verifique nos planos de execução se há operadores Motion custosos e ajuste o design da tabela:

  • Operadores Motion demorados: redesenhe a distribuição.

  • Operadores Motion ineficientes causados por estatísticas desatualizadas: atualize as estatísticas com analyze.

  • Broadcasting de tabelas pequenas: reduza a contagem de shards para otimizar a eficiência do Broadcast Motion.

Otimize agregações

Otimize COUNT DISTINCT

  • Substitua o COUNT DISTINCT exato (que consome muitos recursos) pelo APPROX_COUNT_DISTINCT (mais rápido, taxa de erro de 0,1% a 1%) quando uma pequena variação for aceitável.

  • Troque o COUNT DISTINCT pelo UNIQ (V1.3+).

  • Defina uma chave de distribuição adequada.

    Use a chave do COUNT DISTINCT como chave de distribuição para evitar reorganização de dados entre shards.

  • Atualize para a V2.1+ para obter otimizações integradas.

    A versão V2.1+ inclui otimizações nativas para cenários de COUNT DISTINCT, incluindo um ou mais COUNT DISTINCT, skew de dados e consultas sem GROUP BY.

Force a agregação em vários estágios

A agregação em vários estágios reduz a transferência de dados ao realizar agregações parciais dentro de cada shard primeiro:

set optimizer_force_multistage_agg = on;

Otimize múltiplas funções de agregação na mesma coluna

A partir da V4.0, o Hologres deduplica automaticamente funções de agregação idênticas na mesma coluna, reduzindo a computação. Atualize para a V4.0+ para usar essa otimização.

Exemplo:

-- Create a test table.
CREATE TABLE tbl(x int4, y int4);

-- Insert test data.
INSERT INTO tbl VALUES (1,2), (null,200), (1000,null), (10000,20000);

-- Query data
SELECT
    sum(x + 1),
    sum(x + 2),
    sum(x - 3),
    sum(x - 4)
FROM
    tbl;

O plano de consulta mostra que x é a única chave de agrupamento.

Para desativar:

-- Disable at the session level.
SET hg_experimental_remove_related_group_by_key = off; 

-- Disable at the DB level.
ALTER DATABASE <database_name> SET hg_experimental_remove_related_group_by_key = off; 

Otimize o esquema da tabela e os índices

Escolha formatos de armazenamento

O Hologres suporta armazenamento por linha, por coluna e híbrido. Escolha com base na sua carga de trabalho:

Formato de armazenamento

Ideal para

Compromisso

Armazenamento por linha

Consultas pontuais por chave primária, UPDATE/DELETE frequentes

Baixo desempenho em varreduras de intervalo e agregações

Armazenamento por coluna

Análises, consultas multicoluna, agregações

UPDATE/DELETE e consultas pontuais mais lentos

Armazenamento híbrido linha-coluna

Cargas de trabalho mistas

Maior sobrecarga de armazenamento

Escolha tipos de dados

  • Prefira tipos menores sempre que possível (INT em vez de BIGINT).

  • Especifique a precisão para tipos DECIMAL/NUMERIC.

  • Evite FLOAT ou DOUBLE em colunas de GROUP BY.

  • Use TEXT para maior versatilidade. Minimize N ao usar VARCHAR(N) ou CHAR(N).

  • Prefira TIMESTAMPTZ e DATE em vez de TEXT para datas.

  • Mantenha tipos de dados consistentes nas condições de junção para evitar conversões implícitas.

Projete uma chave primária

As chaves primárias garantem a unicidade dos dados. Selecione um método de deduplicação durante a importação:

  • ignore: Ignora os novos dados.

  • update: Sobrescreve os dados antigos.

Chaves primárias adequadas melhoram os planos de execução, especialmente para consultas GROUP BY.

No modo de armazenamento colunar, as chaves primárias tornam as gravações mais lentas — o throughput geralmente é 3 vezes maior sem elas.

Use uma tabela particionada

O Hologres suporta particionamento de nível único. Um particionamento adequado acelera as consultas, mas partições em excesso criam arquivos pequenos e prejudicam o desempenho.

Nota

Crie partições diárias para dados incrementais a fim de isolar o armazenamento e o acesso.

Cenários aplicáveis:

  • Use DROP ou TRUNCATE em partições inteiras para obter melhor desempenho do que DELETE e sem impacto em outras partições.

  • Isole varreduras em partições específicas ou tabelas filhas.

  • Utilize tabelas particionadas para importações periódicas em tempo real. Por exemplo, use a data como chave de partição. Instruções de exemplo:

  • begin;
    create table insert_partition(c1 bigint not null, c2 boolean, c3 float not null, c4 text, c5 timestamptz not null) partition by list(c4);
    call set_table_property('insert_partition', 'orientation', 'column');
    commit;
    create table insert_partition_child1 partition of insert_partition for values in('20190707');
    create table insert_partition_child2 partition of insert_partition for values in('20190708');
    create table insert_partition_child3 partition of insert_partition for values in('20190709');
    
    select * from insert_partition where c4 >= '20190708';
    select * from insert_partition_child3;

Escolha índices adequados

O Hologres oferece vários tipos de índice. Defina os índices ao criar a tabela:

Tipo

Finalidade

Consulta de exemplo

clustering_key

Consultas de intervalo e filtragem

WHERE created_at > '2024-01-01'

bitmap_columns

Consultas de igualdade

WHERE status = 'active'

segment_key (também conhecida como event_time_column)

Filtragem baseada em tempo (nível de arquivo)

Filtragem rápida no nível de arquivo antes dos índices bitmap ou clustering. Segue a correspondência de prefixo mais à esquerda (geralmente 1 coluna). Use o primeiro timestamp não vazio como segment_key.

WHERE event_time > '2020-01-01';

Observações:

  • As chaves de clustering e segment seguem o princípio de correspondência de prefixo mais à esquerda.

  • Os índices bitmap suportam consultas AND/OR em várias colunas.

  • Use segment_key para filtragem baseada em tempo primeiro, depois bitmap_columns para igualdade ou clustering_key para consultas de intervalo.

Exemplo:

BEGIN;
CREATE TABLE events (
    event_id INT NOT NULL,
    user_id INT NOT NULL,
    event_time TIMESTAMPTZ NOT NULL,
    event_type TEXT
);
CALL set_table_property('events', 'clustering_key', 'event_time');
CALL set_table_property('events', 'segment_key', 'event_time');
CALL set_table_property('events', 'bitmap_columns', 'user_id,event_type');
COMMIT;
Nota

É possível adicionar bitmap_columns após a criação da tabela. Já clustering_key e segment_key devem ser especificadas na criação.

Verifique o uso do índice em uma consulta executando EXPLAIN:

EXPLAIN SELECT * FROM events WHERE event_time > '2026-01-01';

Desative a codificação de dicionário para colunas de caracteres

A codificação de dicionário acelera comparações de strings, mas adiciona sobrecarga de codificação/decodificação. Desative-a para colunas onde o custo de comparação é baixo:

BEGIN;
CREATE TABLE logs (id INT, message TEXT);
CALL set_table_property('logs', 'dictionary_encoding_columns', '');
COMMIT;

Otimize instruções SQL

Evite SQL externo (Postgres), como NOT IN

O Hologres usa o HQE (Hologres Query Engine) para obter o melhor desempenho. Operadores não suportados recorrem ao PQE (Postgres Query Engine), que é mais lento.

Verifique o fallback para PQE nos planos de execução:

EXPLAIN SELECT * FROM orders WHERE id NOT IN (SELECT id FROM cancelled_orders);

Se você vir External SQL (Postgres), reescreva a consulta:

Não suportado pelo HQE

Rreescrever para

Exemplo

Observações

NOT IN

NOT EXISTS

select * from tmp where not exists (select a from tmp1 where a = tmp.a);

N/A.

regexp_split_to_table

unnest(string_to_array)

select name,unnest(string_to_array(age,',')) from demo;

regexp_split_to_table suporta expressões regulares.

A partir do Hologres V2.0.4, o HQE suporta regexp_split_to_table. Ative o GUC com o seguinte comando: set hg_experimental_enable_hqe_table_function = on;

substring

extract(hour from to_timestamp(c1, 'YYYYMMDD HH24:MI:SS'))

select cast(substring(c1, 13, 2) as int) AS hour from t2;

Reescreva como:

select extract(hour from to_timestamp(c1, 'YYYYMMDD HH24:MI:SS')) from t2;

Algumas versões V0.10 e anteriores não suportam substring. A partir da V1.3, o HQE suporta entrada sem regex para substring.

regexp_replace

replace

select regexp_replace(c1::text,'-','0') from t2;

Reescreva como:

select replace(c1::text,'-','') from t2;

replace não suporta expressões regulares.

at time zone 'utc'

Remova at time zone 'utc'

select date_trunc('day',to_timestamp(c1, 'YYYYMMDD HH24:MI:SS')  at time zone 'utc') from t2

Reescreva como:

select date_trunc('day',to_timestamp(c1, 'YYYYMMDD HH24:MI:SS') ) from t2;

N/A.

CAST(text AS timestamp)

to_timestamp

select cast(c1 as timestamp) from t2;

Reescreva como:

select to_timestamp(c1, 'yyyyMMdd hh24:mi:ss') from t2;

Suportado pelo HQE a partir do Hologres V2.0.

timestamp::text

to_char

select c1::text from t2;

Reescreva como:

select to_char(c1, 'yyyyMMdd hh24:mi:ss') from t2;

Suportado pelo HQE a partir do Hologres V2.0.

Evite consultas LIKE difusas

Evite buscas difusas como a operação LIKE, pois elas não utilizam índices.

Otimize consultas ORDER BY LIMIT**

A partir da V1.3, o Hologres suporta Merge Sort para consultas ORDER BY ... LIMIT, eliminando operações de classificação redundantes.

Otimize consultas GROUP BY

Defina a coluna do GROUP BY como chave de distribuição para reduzir a redistribuição de dados.

-- If data is distributed based on the values in column a, runtime data redistribution is reduced, and the parallel computing capability of shards is fully utilized.
select a, count(1) from t1 group by a; 

A partir da V4.0, o Hologres reescreve automaticamente colunas relacionadas do GROUP BY para reduzir mesclagens (profundidade máxima de busca: 5 camadas). Uma cláusula como GROUP BY COL_A, ((COL_A + 1)), ((COL_A + 2)) é reescrita para GROUP BY COL_A. Exemplo:

CREATE TABLE tbl (
    a int,
    b int,
    c int
);

-- Query
SELECT
    a,
    a + 1 as a1,
    a + 2 as a2,
    sum(b)
FROM tbl
GROUP BY
    a,
    a1,
    a2;

O plano de execução confirma a reescrita — a cláusula GROUP BY contém apenas a coluna a.

QUERY PLAN
Gather  (cost=0.00..5.00 rows=1 width=20)
  -> Project  (cost=0.00..5.00 rows=1 width=20)
    -> HashAggregate  (cost=0.00..5.00 rows=1 width=12)
          Group Key: a
        -> Redistribution  (cost=0.00..5.00 rows=1 width=8)
              Hash Key: a
            -> Local Gather  (cost=0.00..5.00 rows=1 width=8)
              -> Seq Scan on tbl  (cost=0.00..5.00 rows=1 width=8)
Query Queue: init_warehouse.default_queue
Optimizer: HQO version 4.0.0

Para desativar:

-- Disable the feature at the session level.
SET hg_experimental_remove_related_group_by_key = off; 

-- Disable the feature at the database level.
ALTER DATABASE <database_name> SET hg_experimental_remove_related_group_by_key = off; 

Ative a reutilização de CTE

Quando uma CTE é referenciada várias vezes, ative a reutilização de CTE para evitar recálculos (V1.3+):

SET optimizer_cte_inlining=off;
Nota
  • A reutilização de CTE vem desativada por padrão. Ative-a manualmente via GUC.

  • A reutilização de CTE depende do Spill no estágio Shuffle. Grandes volumes de dados podem afetar o desempenho devido a taxas de consumo variáveis.

Otimize a análise Top-N

  • Em cenários OLAP, recuperar os N principais registros dentro de um grupo é um requisito comum. Por exemplo, a seguinte consulta SQL recupera os dois principais registros da tabela t dentro de cada partição b, classificados por a:

    CREATE TABLE t (
      a int,
      b int
    );
    
    INSERT INTO t VALUES (2, 1), (3, 1), (4, 1), (5, 2), (6, 2);
    
    SELECT
        *
    FROM (
      SELECT
      a,
      b,
      row_number() OVER (PARTITION BY b ORDER BY a) AS rn
      FROM
      t) t1
    WHERE
        rn <= 2;

    O resultado da execução é o seguinte:

    a	b	rn
    5	2	1
    6	2	2
    2	1	1
    3	1	2
  • A partir do Hologres V4.1, o operador Partition Sort empurra a cláusula LIMIT para dentro da Partition, filtrando dados antecipadamente durante a classificação. Isso reduz a memória necessária para funções de janela como row_number e rank em cenários Top-N, diminuindo o risco de OOM. Ativado por padrão. Para desativar:

    -- Disable the feature at the session level.
    SET hg_experimental_enable_hash_partitioned_sort_v2 = off; 
    
    -- Disable the feature at the database level.
    ALTER DATABASE <database_name> SET hg_experimental_enable_hash_partitioned_sort_v2 = off; 

Lide com skew de dados

A distribuição desigual de dados torna as consultas lentas. Verifique a contagem de linhas por shard para detectar skew:

-- hg_shard_id is a built-in hidden column in each table that describes the shard where the corresponding row of data is located.
SELECT hg_shard_id, count(1) FROM t1 GROUP BY hg_shard_id;

Se alguns shards tiverem significativamente mais linhas do que outros:

  • Altere a distribution_key para uma coluna com distribuição de dados uniforme.

    Importante

    Alterar a chave de distribuição exige recriar a tabela e reimportar os dados.

  • Se os dados forem inerentemente enviesados, otimize sob a perspectiva de negócios.

Desative o cache de resultados para testes

O Hologres armazena resultados de consultas em cache por padrão. Desative o cache ao avaliar o desempenho:

set hg_experimental_enable_result_cache = off;

Informações relacionadas