Todos os produtos
Search
Central de documentação

MaxCompute:Plano de otimização para cálculos de métricas de longo período

Última atualização: Jun 26, 2026

Ao construir data warehouses, empresas de e-commerce frequentemente precisam calcular métricas de janela deslizante, como visitantes únicos (UV), contagem de compradores e compradores recorrentes nos últimos 30 dias. Como esses indicadores são calculados sobre dados acumulados por um longo período, consultas ingênuas de janela deslizante tornam-se excessivamente lentas ou falham completamente em grande escala.

A causa raiz é sempre a mesma: volume excessivo de dados reprocessado do zero a cada execução. As duas abordagens de otimização apresentadas neste tópico compartilham um princípio comum — evitar o recálculo completo por meio de pré-agregação ou acumulação incremental de dados — e diferem apenas na profundidade com que aplicam esse conceito.

Todos os exemplos de código utilizam variáveis de agendamento do DataWorks (por exemplo, ${bdp.system.bizdate} ). Os exemplos se aplicam exclusivamente a nós de agendamento no DataWorks.

O problema das consultas de janela deslizante

Uma consulta típica de UV de 30 dias tem a seguinte estrutura:

SELECT item_id,
       COUNT(DISTINCT visitor_id) AS ipv_uv_1d_001
FROM vistor_item_detail_log
WHERE ds <= ${bdp.system.bizdate}
  AND ds >= TO_CHAR(DATEADD(TO_DATE(${bdp.system.bizdate},'yyyymmdd'),-29,'dd'),'yyyymmdd')
GROUP BY item_id;

Essa consulta varre 30 partições de dados de log brutos em cada execução. Se o volume de logs for elevado, o MaxCompute pode precisar gerar mais de 99.999 tarefas map, ponto em que o job falha. Mesmo abaixo desse limite, varrer 30 dias de logs brutos diariamente gera desperdício, pois a maior parte dos dados não sofreu alterações desde a execução anterior.

Escolha uma abordagem

Dois padrões de otimização resolvem esse problema. Selecione aquele mais adequado à estrutura dos seus dados e consultas:

Abordagem

Funcionamento

Cenário recomendado

Tabela intermediária

Deduplica e agrega logs brutos diariamente em uma tabela de resumo; consulta a tabela de resumo em vez dos logs brutos

Volume diário de logs elevado; dados por partição mudam significativamente entre execuções

Acumulação incremental

Mescla todas as partições históricas em uma única partição e anexa novos dados diariamente

Consultas repetidas da mesma janela deslizante; redução de varreduras multipartição é mais crítica que a deduplicação diária

Para a maioria das cargas de trabalho de e-commerce, comece pela abordagem de tabela intermediária. Migre para acumulação incremental caso as varreduras multipartição continuem sendo o gargalo após a implementação da tabela intermediária.

Abordagem 1: Tabela intermediária

Funcionamento

Em vez de consultar 30 partições de logs brutos, pré-agregue os logs de cada dia em uma tabela de resumo. Cada linha nessa tabela representa um par único (item_id, visitor_id) para aquele dia. Consultar 30 partições de dados pré-agregados custa muito menos do que consultar 30 partições de logs brutos, pois a etapa de pré-agregação elimina linhas duplicadas de alta cardinalidade antes da execução da consulta de janela deslizante.

Etapa 1: Crie o resumo diário

Execute este script como um nó agendado diariamente no DataWorks, antes dos nós de métricas:

INSERT OVERWRITE TABLE mds_itm_vsr_xx (ds='${bdp.system.bizdate} ')
SELECT item_id,
       visitor_id,
       COUNT(1) AS pv
FROM (
    SELECT item_id,
           visitor_id
    FROM vistor_item_detail_log
    WHERE ds = ${bdp.system.bizdate}
    GROUP BY item_id, visitor_id
) a;

Esse comando grava uma linha deduplicada por par (item_id, visitor_id) na tabela mds_itm_vsr_xx referente à partição de data atual.

Etapa 2: Consulte a tabela de resumo

Com a tabela de resumo disponível, sua consulta de janela deslizante processa um volume de dados muito menor:

SELECT item_id,
       COUNT(DISTINCT visitor_id) AS uv,
       SUM(pv) AS pv
FROM mds_itm_vsr_xx
WHERE ds <= '${bdp.system.bizdate} '
  AND ds >= TO_CHAR(DATEADD(TO_DATE('${bdp.system.bizdate} ','yyyymmdd'),-29,'dd'),'yyyymmdd')
GROUP BY item_id;
Importante

Esta abordagem exige um nó diário dedicado para popular a tabela mds_itm_vsr_xx. Configure esse nó como dependência upstream dos seus nós de métricas no DataWorks para garantir que a tabela de resumo esteja sempre atualizada antes da execução das consultas downstream.

Abordagem 2: Acumulação incremental

Funcionamento

A abordagem de tabela intermediária ainda varre 30 partições a cada execução. A acumulação incremental vai além: mescla todos os dados históricos em uma única partição de acumulação e anexa apenas os novos dados diariamente. Assim, as consultas de janela deslizante leem apenas uma partição.

Essa estratégia é mais eficaz quando o percentual de dados alterados diariamente é pequeno em relação ao conjunto histórico total, ou seja, quando a maior parte dos dados na partição de acumulação permanece estável entre as execuções.

Implementação: tabela de dimensão de compradores recorrentes

O caso de uso de compradores recorrentes (clientes que compraram nos últimos 30 dias) ilustra bem essa abordagem. Uma solução ingênua varre 30 partições de logs de faturamento em cada execução:

SELECT item_id,
       buyer_id AS old_buyer_id
FROM buyer_item_detail_log
WHERE ds < ${bdp.system.bizdate}
  AND ds >= TO_CHAR(DATEADD(TO_DATE(${bdp.system.bizdate},'yyyymmdd'),-29,'dd'),'yyyymmdd')
GROUP BY item_id,
         buyer_id;

Alternativamente, mantenha uma tabela de dimensões onde cada linha representa o relacionamento entre um comprador e um item, registrando campos como hora da primeira compra, hora da última compra, total de itens comprados e gasto total. Atualize-a diariamente com os logs de faturamento do dia anterior.

Para determinar se um comprador é recorrente, verifique se o campo last_purchase_time está dentro dos últimos 30 dias. Isso substitui a varredura de 30 partições de logs de faturamento por uma consulta em partição única na tabela de dimensões, eliminando a deduplicação por varredura completa a cada execução.

Considerações de desempenho

Fator

Tabela intermediária

Acumulação incremental

Partições varridas por execução

30 (com linhas menores)

1

Complexidade de implementação

Baixa: um nó diário adicional

Mais alta: lógica de mesclagem e gerenciamento de dependências

Atualização dos dados

Diária

Diária

Melhor adequação

Grande volume diário de logs com chaves de alta cardinalidade

Consultas repetidas de janela deslizante sobre dados históricos estáveis

Ambas as abordagens transferem o processamento custoso do momento da consulta para o momento da ingestão. A tabela intermediária faz isso diariamente; a acumulação incremental aplica esse princípio a todos os dias históricos.