すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:MAPJOIN HINT

最終更新日:Nov 10, 2025

大きなテーブルと複数の小さなテーブルを join する場合は、MAPJOIN ヒントを SELECT 文で明示的に指定して、クエリのパフォーマンスを向上させることができます。このトピックでは、MAPJOIN ヒント を使用してテーブルを結合する方法について説明します。

説明

JOIN 操作には、マップ、シャッフル、縮小の 3 つの段階があります。ほとんどの場合、テーブルは縮小ステージで join されます。

MAPJOIN は、縮小ステージではなくマップステージでテーブルを結合します。これにより、データ転送が高速化され、システムリソースの消費が削減され、ジョブのパフォーマンスが最適化されます。

マップステージでは、MAPJOIN は、指定された小さなテーブルのすべてのデータを、JOIN 操作を実行するプログラムのメモリにロードします。これにより、JOIN 操作の効率が向上します。

MaxCompute SQL では、ON 条件で非等値 join または OR ロジックを使用することはできません。ただし、MAPJOIN ではこれを行うことができます。

制限

MAPJOIN の使用に関する制限:

  • マップステージでは、MAPJOIN は、指定されたテーブルのすべてのデータを JOIN 操作を実行するプログラムのメモリにロードします。MAPJOIN に指定されたテーブルは小さなテーブルである必要があり、テーブルデータによって占有される合計メモリは 512 MB を超えることはできません。MaxCompute は、保存前にデータを圧縮します。小さなテーブルがメモリにロードされると、テーブルのデータ量は急激に増加します。512 MB は、小さなテーブルがメモリにロードされた後の最大データ量を示します。

    説明

    ここで示す 512 MB は、小さなテーブルがメモリにロードされて解凍された後に占有する最大メモリサイズを指し、MaxCompute に圧縮されて保存された後の小さなテーブルのファイルサイズではありません。

  • MAPJOIN での JOIN 操作の制限:

    • LEFT OUTER JOIN 操作の左側のテーブルは大きなテーブルである必要があります。

    • RIGHT OUTER JOIN 操作の右側のテーブルは大きなテーブルである必要があります。

    • FULL OUTER JOIN 操作では MAPJOIN を使用できません。

    • INNER JOIN 操作の左側または右側のテーブルは大きなテーブルにすることができます。

  • MaxCompute では、MAPJOIN に最大 128 個の小さなテーブルを指定できます。128 個を超える小さなテーブルを指定すると、構文エラーが返されます。

使用上の注意

MAPJOIN は、/*+ mapjoin(<table_name>) */ ヒントを SELECT 文に追加した後にのみ実行できます。次の項目に注意してください。

  • 小さなテーブルまたはサブクエリを参照する場合は、テーブルまたはサブクエリのエイリアスを参照する必要があります。

  • MAPJOIN では、サブクエリを小さなテーブルとして使用できます。

  • MAPJOIN では、非等値結合を使用したり、OR を使用して条件を組み合わせたりできます。ON 条件を指定せずに MAPJOIN ON 1 = 1 を使用してデカルト積を計算できます(例:select /*+ mapjoin(a) */ a.id from shop a join table_name b on 1=1;)。ただし、この計算方法ではデータ量が増加する可能性があります。

  • MAPJOIN の複数の小さなテーブルはコンマ (,) で区切ります(例:/*+ mapjoin(a,b,c)*/)。

説明

SCALAR、IN、NOT IN、EXISTS、NOT EXISTS などの一部のサブクエリは、実行中に JOIN 操作に変換できます。MAPJOIN は効率的な JOIN アルゴリズムです。SUBQUERY の結果が小さなテーブルの場合は、サブクエリ文で HINT を使用して MAPJOIN アルゴリズムを明示的に指定できます。

サンプルデータ

このトピックの例をよりよく理解するために、サンプルのソースデータが提供されています。この例では、sale_detail テーブルと sale_detail_sj テーブルが作成され、データがテーブルに挿入されます。

-- sale_detail という名前のパーティションテーブルを作成します。
/* 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);

-- sale_detail テーブルと sale_detail_sj テーブルにパーティションを追加します。
/* sale_detail テーブルと sale_detail_sj テーブルにパーティションを追加します。 */
alter table sale_detail add partition (sale_date='2013', region='china');
alter table sale_detail_sj add partition (sale_date='2013', region='china');

-- sale_detail テーブルと sale_detail_sj テーブルにデータを挿入します。
/* sale_detail テーブルと sale_detail_sj テーブルにデータを挿入します。 */
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);

sale_detail テーブルと sale_detail_sj テーブルで JOIN 操作を実行します。操作は、次の条件のいずれかを満たす必要があります。1. sale_detail_sj テーブルの total_price 列の合計値が、sale_detail テーブルの total_price 列の合計値よりも小さい。2. sale_detail_sj テーブルの total_price 列の値と sale_detail テーブルの total_price 列の値の合計が 500 未満である。サンプル文:

-- パーティションテーブルのフルスキャンを許可します。
/* パーティションテーブルのフルスキャンを許可します。 */
SET odps.sql.allow.fullscan=true;

-- MAPJOIN を使用してクエリを実行します。
/* MAPJOIN を使用してクエリを実行します。 */
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;

次の結果が返されます。

+-----------+-------------+--------------+
| 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        |
+-----------+-------------+--------------+