Todos os produtos
Search
Central de documentação

MaxCompute:MAPJOIN HINT

Última atualização: Jun 26, 2026

Adicione um hint MAPJOIN a uma instrução SELECT para forçar a execução do join na fase de map, ignorando as fases de shuffle e reduce. Essa abordagem reduz a sobrecarga de transmissão de dados e melhora o desempenho da consulta ao unir uma tabela grande com uma ou mais tabelas pequenas. Utilize o MAPJOIN quando o otimizador não aplicar automaticamente o join na fase de map à sua consulta.

Como funciona

Um JOIN padrão no MaxCompute passa por três fases: map, shuffle e reduce. A lógica real do join é executada na fase de reduce, o que exige o shuffle de dados entre os nós.

O MAPJOIN altera esse fluxo: ele carrega todo o conteúdo da tabela pequena especificada na memória durante a fase de map. Cada mapper realiza o join localmente com os dados em memória, eliminando completamente as fases de shuffle e reduce.

O hint indica a tabela pequena a ser carregada na memória. Para cada mapper que lê linhas da tabela grande, a tabela pequena é lida integralmente da memória:

SELECT /*+ mapjoin(a) */ a.shop_name, a.total_price, b.total_price
FROM sale_detail_sj a JOIN sale_detail b
ON a.total_price < b.total_price OR a.total_price + b.total_price < 500;

Neste exemplo, a (alias de sale_detail_sj) é a tabela pequena. O hint especifica a, portanto, é a que será carregado na memória de cada mapper.

Limites

Memória e quantidade de tabelas

Restrição

Limite

Observações

Memória total para todas as tabelas pequenas

512 MB

Medido após o carregamento e descompactação dos dados na memória, não corresponde ao tamanho compactado armazenado no MaxCompute

Número máximo de tabelas pequenas

128

Especificar mais de 128 tabelas resulta em erro de sintaxe

Tipos de JOIN suportados

Tipo de JOIN

Suportado

Requisito

INNER JOIN

Sim

A tabela grande pode ser a da esquerda ou a da direita

LEFT OUTER JOIN

Sim

A tabela da esquerda deve ser a tabela grande

RIGHT OUTER JOIN

Sim

A tabela da direita deve ser a tabela grande

FULL OUTER JOIN

Não

Observações de uso

Insira /*+ mapjoin(<table_name>) */ imediatamente após SELECT. Considere os pontos a seguir:

  • Use aliases em vez dos nomes originais das tabelas. Se a tabela pequena ou subconsulta possuir um alias, utilize-o dentro do hint.

  • Subconsultas são aceitas como tabelas pequenas. Substitua a referência à tabela por uma subconsulta e use o alias correspondente no hint.

  • Separe múltiplas tabelas pequenas com vírgulas: /*+ mapjoin(a,b,c) */

  • Joins não equitativos e condições OR são permitidos. O SQL padrão do MaxCompute não aceita joins não equitativos nem lógica OR na condição ON, mas o MAPJOIN permite ambos.

  • Produtos cartesianos são suportados com ON 1 = 1 (por exemplo, SELECT /*+ mapjoin(a) */ a.id FROM shop a JOIN table_name b ON 1=1), porém isso pode aumentar significativamente o volume de dados de saída.

Nota

Tipos de subconsulta como SCALAR, IN, NOT IN, EXISTS e NOT EXISTS podem ser convertidos em operações JOIN durante a execução. Caso o resultado da subconsulta se qualifique como tabela pequena, adicione um hint MAPJOIN à instrução da subconsulta para aplicar explicitamente o algoritmo de join na fase de map.

Dados de exemplo

Os exemplos deste tópico utilizam as tabelas sale_detail e sale_detail_sj. Execute as instruções abaixo para criar as tabelas e inserir dados de amostra.

-- Create a partitioned table named sale_detail.
CREATE TABLE IF NOT EXISTS sale_detail
(
  shop_name     STRING,
  customer_id   STRING,
  total_price   DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);

CREATE TABLE IF NOT EXISTS sale_detail_sj
(
  shop_name     STRING,
  customer_id   STRING,
  total_price   DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);

-- Add partitions.
ALTER TABLE sale_detail ADD PARTITION (sale_date='2013', region='china');
ALTER TABLE sale_detail_sj ADD PARTITION (sale_date='2013', region='china');

-- Insert sample data.
INSERT INTO sale_detail PARTITION (sale_date='2013', region='china')
VALUES ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);

INSERT INTO sale_detail_sj PARTITION (sale_date='2013', region='china')
VALUES ('s1','c1',100.1),('s2','c2',100.2),('s5','c2',100.2),('s2','c2',100.2);

Exemplo

Una sale_detail_sj (tabela pequena, com alias a) a sale_detail (tabela grande, com alias b) usando uma condição não equitativa. Retorne as linhas em que o total_price de a seja menor que o total_price de b, ou em que a soma dos dois preços seja inferior a 500.

-- Allow a full scan on the partitioned table.
SET odps.sql.allow.fullscan=true;

-- Use MAPJOIN with a non-equi join condition.
SELECT /*+ mapjoin(a) */
    a.shop_name,
    a.total_price,
    b.total_price
FROM sale_detail_sj a JOIN sale_detail b
ON a.total_price < b.total_price OR a.total_price + b.total_price < 500;

A consulta retorna o seguinte resultado:

+-----------+-------------+--------------+
| shop_name | total_price | total_price2 |
+-----------+-------------+--------------+
| s1        | 100.1       | 100.1        |
| s2        | 100.2       | 100.1        |
| s5        | 100.2       | 100.1        |
| s2        | 100.2       | 100.1        |
| s1        | 100.1       | 100.2        |
| s2        | 100.2       | 100.2        |
| s5        | 100.2       | 100.2        |
| s2        | 100.2       | 100.2        |
| s1        | 100.1       | 100.3        |
| s2        | 100.2       | 100.3        |
| s5        | 100.2       | 100.3        |
| s2        | 100.2       | 100.3        |
+-----------+-------------+--------------+