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

MaxCompute:ハッシュクラスタリング

最終更新日:Sep 16, 2025

MaxComputeでは、ハッシュクラスタリングを有効にするために、テーブルのシャッフルプロパティとソートプロパティを設定できます。 ハッシュクラスタ化テーブルは、データのストレージ特性に基づいて、実行計画の最適化、運用効率の向上、リソースの節約に役立ちます。 このトピックでは、MaxComputeでハッシュクラスタ化テーブルを使用する方法について説明します。

背景情報

MaxComputeを使用してデータをクエリする多くのシナリオでは、テーブルを結合する必要があります。 次のサンプルステートメントでは、データクエリにテーブル間の単純な内部結合を使用します。 t1およびt2テーブルは、id列に基づいて結合されます。

SELECT t1.a, t2.b FROM t1 JOIN t2 ON t1.id = t2.id;

MaxComputeは、次の結合方法を提供します。

  • ブロードキャストハッシュ結合

    結合するテーブルの1つがスモールテーブルである場合、MaxComputeはブロードキャストハッシュ結合メソッドを使用してすべての結合タスクインスタンスにスモールテーブルをブロードキャストし、スモールテーブルとビッグテーブルの間でハッシュ結合を実行します。

  • ハッシュ結合のシャッフル

    結合されるべきテーブルの両方が大きい場合、テーブルデータはブロードキャストされ得ない。 この場合、ハッシュシャッフルは、結合キーに基づいて2つのテーブルに対して別々に実行される。 キー値が同じ場合、ハッシュ結果は同じです。 このようにして、同じキー値を持つレコードが同じ結合タスクインスタンスに配布されます。 次に、各インスタンスは、小さい方のテーブルからのデータレコードのハッシュテーブルを作成し、結合キーに基づいて、ハッシュテーブル内のデータを大きい方のテーブルからのデータと順番に結合します。

  • マージ結合の並べ替え

    結合されるテーブルの両方が非常に大きい場合、シャッフルハッシュ結合方法はこのシナリオには適していません。 これは、メモリリソースがハッシュテーブルを作成するのに十分でないためです。 この場合、ハッシュシャッフルは、結合キーに基づいて2つのテーブルに対して別々に実行される。 次に、結合キーに基づいてデータがソートされます。 最後に、2つのテーブルからのソートされたデータレコードが結合される。 次の図では、ソートマージ結合のプロセスについて説明します。流程MaxComputeのデータ量に関しては、ほとんどの場合、ソートマージ結合方法が使用されます。 しかし、ソートマージ結合方法は、多くのリソースを消費する。 上の図では、データがシャッフルされるときに計算操作が実行されます。 中間の結果はディスクに保存されます。 リデューサーが後続の操作でデータを読み取る場合、データの読み取りとソートも必要です。 MマッパーとRリデューサーが展開されるシナリオでは、M × RのI/O操作が含まれます。 次の図は、Fuxiジョブの物理実行プランを示しています。 実行プランでは、2つのマップステージと1つの結合ステージが必要です。 赤いボックス内の操作は、シャッフルおよびソート操作です。Execution plan of a Fuxi jobいくつかの結合動作は、データクエリにおいて繰り返し実行され得る。 たとえば、元のクエリ文を次の文に変更できます。

    SELECT t1.c, t2.d FROM t1 JOIN t2 ON t1.id = t2.id;

    このステートメントでは、選択された列は元のクエリステートメントの列とは異なりますが、JOIN句は同じで、シャッフルとソートのプロセス全体は同じです。

    元のクエリ文を次の文に変更することもできます。

    SELECT t1.c, t3.d FROM t1 JOIN t3 ON t1.id = t3.id;

    このステートメントでは、t1とt3テーブルが結合されます。 ただし、t1テーブルの場合、シャッフルとソートのプロセス全体は同じです。

    シャッフルと並べ替えの操作が繰り返されるのを防ぐために、テーブルの作成時にハッシュシャッフルとデータ並べ替えに基づいてテーブルデータをMaxComputeに保存できます。 このように、いくつかの追加の操作がテーブル作成プロセスで実行されますが、シャッフル操作と結合操作はデータクエリ中に繰り返し実行されません。 次の図は、前述のストレージ特性を持つテーブルを結合するFuxiジョブの物理実行プランを示しています。 このプランでは、シャッフルおよびソート操作の繰り返しは実行されなくなり、3つのステージが1つのステージに変更されます。Hash shuffle

手順

ハッシュクラスタ化テーブルの作成

次のステートメントを使用して、ハッシュクラスタ化テーブルを作成できます。 ステートメントでは、CLUSTERED BYおよびINTO number_of_buckets BUCKETSパラメーターを設定する必要があります。 CLUSTERED BYパラメーターは、ハッシュキーとも呼ばれるクラスターキーを指定します。 INTO number_of_buckets BUCKETSパラメーターは、バケットの数を指定します。 SORTED BYパラメーターはオプションです。 最適な最適化パフォーマンスを実現するには、CLUSTERED BYパラメーターと同じ値を指定することを推奨します。

  • 構文

    CREATE TABLE [IF NOT EXISTS] <table_name>
                 [(<col_name> <data_type> [comment <col_comment>], ...)]
                 [comment <table_comment>]
                 [PARTITIONED BY (<col_name> <data_type> [comment <col_comment>], ...)]
                 [CLUSTERED BY (<col_name> [, <col_name>, ...])
                 [SORTED BY (<col_name> [ASC | DESC] [, <col_name> [ASC | DESC] ...])]
                 INTO <number_of_buckets> BUCKETS] [AS <select_statement>]
    • パーティション分割されていないテーブル

      CREATE TABLE T1 (a string, b string, c bigint)
                   CLUSTERED BY (c)
                   SORTED by (c) INTO 1024 BUCKETS;
    • パーティションテーブル

      CREATE TABLE T1 (a string, b string, c bigint)
             PARTITIONED BY (dt string)
             CLUSTERED BY (c)
             SORTED by (c) INTO 1024 BUCKETS;
  • パラメーター

    • クラスター

      MaxComputeが指定された列に対してハッシュ操作を実行するハッシュキーを指定します。 ハッシュ操作が実行されると、MaxComputeはハッシュ値に基づいてデータをバケットに分散します。 データスキューやホットスポットの問題を防ぎ、同時実行効率を向上させるために、CLUSTERED BYでは、値の範囲が大きく、重複するキー値の数が少ない列を指定することをお勧めします。 結合操作を最適化するには、一般的に使用される結合キーまたは集計キーを選択することを推奨します。 結合キーおよび集合キーは、従来のデータベースにおける主キーと同様である。

    • によって歌われた

      バケット内のフィールドをソートする方法を指定します。 クエリのパフォーマンスを向上させるために、SORTED BYの設定をCLUSTERED BYパラメーターの設定と一致させることを推奨します。 SORTED BYパラメーターを指定すると、MaxComputeは自動的にインデックスを生成し、インデックスに基づいてクエリを高速化します。

    • 番号_of_bucketsバケットへ

      バケットの数を指定します。 このパラメータは必須であり、データ量に基づいて決定されます。 バケットが多いほど、ジョブの同時実行性が高く、実行効率が高いことを示します。 しかしながら、過剰な数のバケットが存在する場合、過剰な小さなファイルが生成され得る。 過度に高い同時実行もCPU時間を増加させます。 各バケットのデータサイズは500 MB〜1 GBにすることを推奨します。 テーブルが非常に大きい場合は、各バケットのデータサイズを適切に増やすことができます。 結合最適化シナリオでは、シャッフルおよびソートステップを2つのテーブルの結合操作から削除する必要があります。 したがって、テーブル内のバケット数は、他のテーブル内のバケット数の倍数でなければなりません。 例えば、一方のテーブルは256個のバケットを有し、他方のテーブルは512個のバケットを有する。 バケットの数を、512、1,024、2,048、4,096などのN乗の2に設定することを推奨します。 これにより、MaxComputeはバケットを自動的に分割およびマージし、シャッフルとソートのステップを削除できます。

テーブルのハッシュクラスタリングプロパティの変更

パーティションテーブルの場合、MaxComputeではALTER tableステートメントを実行して、ハッシュクラスタリングプロパティをテーブルに追加したり、ハッシュクラスタリングプロパティをテーブルから削除したりできます。

  • 構文

    -- Change a table to a hash-clustered table.
    ALTER TABLE <table_name> [CLUSTERED BY (<col_name> [, <col_name>, ...])
                           [SORTED BY (<col_name> [ASC | DESC] [, <col_name> [ASC | DESC] ...])]
                           INTO <number_of_buckets> BUCKETS];
    -- Change a hash-clustered table to a non-hash-clustered table.
    ALTER TABLE <table_name> NOT CLUSTERED;
  • 使用上の注意

    • ALTER TABLEステートメントは、パーティション分割テーブルのクラスタリングプロパティのみを変更できます。 クラスタリングプロパティは、パーティション分割されていないテーブルに追加した後は変更できません。

    • ALTER TABLEステートメントは、INSERT OVERWRITEステートメントを使用して生成された新しいパーティションを含む、テーブルの新しいパーティションに対してのみ有効です。 新しいパーティションは、ハッシュクラスタリングプロパティに基づいて格納されます。 既存のパーティションのストレージ形式は変更されません。

    • ALTER TABLE文は、テーブルの新しいパーティションに対してのみ有効です。 したがって、このステートメントでパーティションを指定することはできません。

ALTER TABLEステートメントは、既存のテーブルにのみ適しています。 ハッシュクラスタリングプロパティが既存のテーブルに追加された後、ハッシュクラスタリングプロパティに基づいて新しいパーティションが格納されます。

テーブルのプロパティを明示的に検証する

ハッシュクラスタ化テーブルを作成した後、次のステートメントを実行してテーブルのプロパティを表示できます。 ハッシュクラスタリングのプロパティは、返された結果の拡張情報に表示されます。

DESC EXTENDED <table_name>;

次の図は、返される結果の例を示しています。 Verify table propertiesパーティションテーブルの場合、テーブル内のパーティションのプロパティを表示するには、次のステートメントも実行する必要があります。

DESC EXTENDED <table_name> partition(<pt_spec>);

次の図は、返される結果の例を示しています。 Verify hash properties of a partitioned table

ハッシュクラスタリングの利点

バケットの剪定とインデックスの最適化

次のサンプルステートメントは、クエリ操作を示しています。

CREATE TABLE t1 (id bigint, 
                 a string, 
                 b string)
             CLUSTERED BY (id)
             SORTED BY (id) into 1000 BUCKETS; 
... 
SELECT t1.a, t1.b FROM t1 WHERE t1.id=12345;

共通テーブルの場合、クエリ操作には完全なテーブルスキャン操作が必要です。 テーブルのデータ量が多すぎると、多くのリソースを消費する可能性があります。 上記のCREATE TABLEステートメントでは、データはハッシュシャッフルされ、id列に基づいてソートされます。 このようにして、クエリ操作は著しく単純化される。

  1. クエリジョブは、値12345に対応するバケットを見つけることができます。 このように、ジョブは、すべての1,000バケットではなく、単一のバケット内のデータをスキャンする必要があります。 このプロセスはバケットプルーニングと呼ばれます。

  2. バケット内のデータは、id列に基づいてソートおよび保存されます。 MaxComputeは自動的にインデックスを作成し、INDEX LOOKUP関数を使用して関連するレコードを検索します。

これにより、マッパーの数と、MaxComputeによってロードされて読み取られるデータの量が大幅に削減されます。 ロードおよび読み取りされるデータの量を減らすために、MaxComputeでは、マッパーがインデックスを使用してデータが保存されているページを直接検索できます。

たとえば、ビッグデータタスクの場合、合計1,111のマッパーを使用して42.7億のレコードを読み取り、最終結果で26のレコードを照合します。 全体のプロセスは1分48秒かかります。 同じデータと同じクエリで、ハッシュクラスタ化テーブルを使用する場合は、単一のバケットを直接検索し、インデックスを使用して特定のページからデータを読み取ることができます。 このようにして、4つのマッパを使用して10,000レコードを読み取る。 全体のプロセスはわずか6秒かかります。

集約最適化

次のサンプルステートメントは、クエリ操作を示しています。

SELECT department, SUM(salary) FROM employee GROUP BY (department);

ほとんどの場合、テーブルからdepartment列のデータを照会すると、department列のデータがシャッフルされ、ソートされます。 そして、ストリーム集約操作を行い、departmentでデータをグループ化する。 ただし、テーブルの作成時にCLUSTERED BY (department) とSORTED BY (department) をステートメントで指定すると、クエリ操作にはシャッフル操作と並べ替え操作は不要になります。

ストレージの最適化

計算の最適化に加えて、テーブルがシャッフルされ、ソートされた方法で格納される場合、ストレージスペースが大幅に節約されます。 MaxComputeは、基になるレイヤーで列ストアを使用します。 同じまたは類似のキー値を有するレコードは、エンコードおよび圧縮を容易にするソート機能によって一緒に格納される。 このようにして、圧縮効率は著しく改善される。 いくつかの極端なテストケースでは、データがソートされているテーブルは、データがソートされていないテーブルと比較して、ストレージスペースの50% を節約できます。 テーブルのライフサイクルが長い場合は、テーブルをハッシュクラスタ化テーブルとして構成することを推奨します。

例えば、簡単な実験が行われる。 この実験では、TPC-Hデータセットに100 GBのデータを含むlineitemテーブルを使用します。 テーブルには、INTDOUBLESTRINGなどのさまざまなデータ型のデータが含まれています。 同じデータと同じ圧縮方法が使用されている場合、ハッシュクラスタ化テーブルはストレージスペースの約10% を節約できます。 以下の図は、比較結果を示す。

  • ハッシュクラスタリングは使用されません。 Before storage optimization

  • ハッシュクラスタリングが使用される。 After storage optimization

テストデータと分析

このセクションでは、ハッシュクラスタリングによってもたらされる全体的なパフォーマンス改善を測定するための標準TPC-Hデータセットのテストについて説明します。 テストでは、1テラバイトのデータが500バケットに格納されます。 少量のデータが格納されているテーブルと地域テーブルを除いて、他のテーブルの最初の列がクラスターキーとソートキーとして使用されます。 全体的なテスト結果は、テーブルがハッシュクラスタ化された後、合計CPU時間が約17.3% 減少し、合計ジョブ実行時間が約12.8% 減少したことを示しています。

クラスタリングプロパティは、TPC-Hデータセットの一部のクエリ操作、特に2つの最も時間のかかるクエリ操作には使用できません。 したがって、総効率の改善は完全に明らかではありません。 クラスタリングプロパティが使用されるクエリ操作では、効率の改善は完全に明らかです。 例えば、クエリ効率は、TPC-H Q4で約68% 、TPC-H Q12で約62% 、TPC-H Q10で約47% 改善される。

次の図は、TPC-HのQ4クエリが共通テーブルに対して実行されるFuxiジョブの実行計画を示しています。Execution plan of a Fuxi job次の図は、テーブルのハッシュクラスタリングを有効にした後のFuxiジョブの実行計画を示しています。 実行計画では、有向非巡回グラフ (DAG) が大幅に簡略化されており、これがパフォーマンス向上の鍵となります。 Execution plan of a Fuxi job after optimization