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

MaxCompute:小ファイルのマージ

最終更新日:Mar 26, 2026

増分書き込みの繰り返し実行、SQL ジョブ、および Tunnel インポートでは、各タスクごとに個別の出力ファイルが生成されます。時間の経過とともに、パーティションには数千もの 64 MB 未満の小ファイルが蓄積します。これによりクエリ性能が低下し、Pangu ストレージ(Apsara Distributed File System:ADFS)への負荷が増加します。小ファイルのマージは、これらのファイルを少数の大きなファイルに統合することで、クエリ性能を回復させます。

MaxCompute では、ほとんどのマージ処理が自動で実行されます。自動マージが継続的な書き込みペースに追いつかない場合にのみ、手動で MERGE SMALLFILES コマンドを実行してください。

仕組み

MaxCompute では、小ファイルの蓄積を制御するために以下の 2 つのメカニズムが用いられます。

自動マージ — ジョブの完了後、パーティション内のファイル数がしきい値を超えると、MaxCompute は Fuxi タスクを割り当てて小ファイルをマージします。デフォルトでは、1 つの Fuxi インスタンスが処理できる小ファイルの最大数は 100 個です。ジョブログ内の MergeTask エントリにより、自動マージが実行されたことを確認できます。また、MaxCompute は定期的にメタデータベースをスキャンし、ファイル数が多いテーブルまたはパーティションに対して小ファイルのマージを実行します。

手動マージ — データがテーブルに継続的に書き込まれ、自動マージが追いつかない場合は、書き込みジョブを停止し、手動で MERGE SMALLFILES コマンドを実行します。

制限事項

  • 小ファイルのマージには計算リソースが消費されます。従量課金インスタンスでは、SQL の従量課金と同率で課金されます。料金の詳細については、「課金(従量課金)」をご参照ください。

  • MERGE SMALLFILES コマンドはトランザクションテーブルをサポートしていません。トランザクションテーブルのコンパクションを行う場合は、代わりに COMPACTION コマンドをご利用ください。

テーブル内のファイル数の確認

テーブルまたはパーティションに含まれるファイル数を確認するには、DESC EXTENDED コマンドを実行します。

構文

DESC EXTENDED <table_name> [PARTITION (<pt_spec>)];

パラメーター

パラメーター必須説明
table_nameはい対象のテーブル名
pt_specいいえ対象のパーティション。形式:(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)

実行例の出力

结果示例

上記の例では、odl_bpm_wfc_task_log テーブルについて、ファイル数が 3,607 個、合計サイズが 274 MB(287,869,658 バイト)、平均ファイルサイズが約 0.07 MB であることが示されています。このパーティションはマージの適切な候補です。

マージのタイミング:パーティション内のファイル数が 100 個を超え、かつ平均ファイルサイズが 64 MB を下回る場合、小ファイルのマージを行ってください。

小ファイルのマージ

SQL コマンドの使用

必要に応じて小ファイルをマージするには、以下のコマンドを実行します。

ALTER TABLE <table_name> [PARTITION (<pt_spec>)] MERGE SMALLFILES;

マージ後の結果として、odl_bpm_wfc_task_log テーブルのファイル数は 3,607 個から 19 個へ減少し、ストレージ使用量は 274 MB から 37 MB へ削減されます。

即时合并

デフォルトのパラメーター設定は、ほとんどのケースで有効です。必要に応じて、以下の SET パラメーターを用いてマージ動作を調整できます。

パラメーター説明デフォルト
odps.merge.cross.pathsパス間でのファイルマージを許可するかどうか。この値を true に設定すると、パス構造を変更せずに各パス内の小ファイルを個別にマージします。
odps.merge.smallfile.filesize.thresholdマージ対象となるファイルサイズの上限(MB 単位)。未設定の場合、グローバル変数 odps_g_merge_filesize_threshold(デフォルト:32 MB)が使用されます。上書きする場合は、32 より大きい値を指定してください。32 MB
odps.merge.maxmerged.filesize.thresholdマージ後の単一出力ファイルの最大サイズ(MB 単位)。この上限に達すると、新しい出力ファイルが作成されます。未設定の場合、グローバル変数 odps_g_max_merged_filesize_threshold(デフォルト:500 MB)が使用されます。上書きする場合は、500 より大きい値を指定してください。500 MB
odps.merge.max.filenumber.per.instance1 つのマージインスタンスが処理可能なファイル数の上限
odps.sql.mapper.merge.limit.sizeFuxi インスタンスが読み取るファイルの合計サイズの上限

PyODPS の使用

PyODPS を使用すると、マージタスクを非同期で送信できます。これは、前日のジョブによって生成された複数のパーティションをまとめてマージする際に便利です。

以下のすべての例では、odps.run_merge_files() を用いてパーティションごとに非同期マージタスクを送信し、その後すべてのタスクが完了するまで待機しています。

import os
from odps import ODPS

# 環境変数から認証情報を読み込みます。
# コード内に AccessKey ID や AccessKey Secret を直接記述しないでください。
o = ODPS(
    os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    project='<your-project>',
    endpoint='<your-endpoint>',
)

# <table_name> をご利用のテーブル名に置き換えます。
table_name = '<table_name>'
t = o.get_table(table_name)

# マージオプションを設定します。
hints = {'odps.merge.maxmerged.filesize.threshold': 256}

# 対象日付のパーティションごとに 1 つのマージタスクを送信します。
# <datetime> を対象日付(例:'20240101')に置き換えます。
insts = []
for partition in t.iterate_partitions(spec='ds=<datetime>'):
    instance = o.run_merge_files(table_name, str(partition), hints=hints)
    # この Logview URL を開き、「Waiting Queue」をクリックすると、マージジョブログを確認できます。
    print(instance.get_logview_address())
    insts.append(instance)

# すべてのマージタスクの完了を待機します。
for inst in insts:
    inst.wait_for_completion()

スクリプトを実行する前に、以下のプレースホルダーを置き換えてください。

プレースホルダー説明
<your-project>ご利用の MaxCompute プロジェクト名my_project
<your-endpoint>ご利用の MaxCompute エンドポイント<your-region-endpoint>
<table_name>マージ対象のテーブルmy_log_table
<datetime>対象パーティションの日付値20240101

スクリプトを実行する前に、PyODPS をインストールしてください。インストール手順については、「PyODPS ドキュメント」をご参照ください。

実行例

データ安定性チェックにより、tbcdm.dwd_tb_log_pv_di テーブルのマージが必要であることが判明しました。メタデータテーブル tbcdm.dws_rmd_merge_task_1d をクエリすると、ほとんどのパーティションでファイル数が 1,000 個を超え、一部では 7,000 個を超えており、さらにいくつかのパーティションでは平均ファイルサイズが 1 MB を下回っていることが明らかになりました。

使用示例

以下のコマンドを実行して小ファイルをマージします。

SET odps.merge.cross.paths=true;
SET odps.merge.smallfile.filesize.threshold=128;
SET odps.merge.max.filenumber.per.instance = 2000;
ALTER TABLE tbcdm.dwd_tb_log_pv_di PARTITION (ds='20151116') MERGE SMALLFILES;

マージ後の結果:

优化结果

次のステップ

  • COMPACTION — トランザクションテーブル内のデータをコンパクションします

  • 課金(従量課金) — マージジョブの課金について理解します