1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【データエンジニア】部分抽出 vs 全抽出|知っておくべきETL戦略の使い分け

Posted at

はじめに

データエンジニアリングの世界でETL(Extract, Transform, Load)パイプラインを設計する際、最初に直面する重要な選択肢が「データをどのように抽出するか」です。

この記事では、データ抽出の2大戦略である全抽出(Full Load)部分抽出(Incremental Load) の違いを解説し、それぞれの適切な使い分けについて紹介します。

対象読者

  • データエンジニアリングを学び始めた方
  • ETL/ELTパイプラインの設計・構築に携わる方
  • データウェアハウスの運用を担当している方

この記事で学べること

  • 全抽出と部分抽出の基本的な仕組み
  • それぞれのメリット・デメリット
  • 実践での使い分け方

全抽出(Full Load)とは

全抽出(Full Load) とは、ソースシステムからデータセット全体を抽出し、ターゲットシステムに転送する方式です。

処理の流れ

  1. ソースシステムから全データを取得
  2. ターゲットシステムの既存データを削除(または上書き)
  3. 取得した全データをターゲットに挿入

SQLイメージ

full_load_example.sql
-- ターゲットテーブルを空にする
TRUNCATE TABLE target_table;

-- ソースから全データを挿入
INSERT INTO target_table
SELECT * FROM source_table;

メリット

メリット 説明
実装がシンプル 変更検知ロジックが不要で、実装・保守が容易
データ整合性が高い 毎回全データを同期するため、ソースとターゲットの不整合が起きにくい
削除データの反映 ソースで削除されたレコードも自動的に反映される

デメリット

デメリット 説明
処理時間が長い データ量に比例して処理時間が増加
リソース消費が大きい CPU・メモリ・ネットワーク帯域を大量に使用
コストが高い クラウド環境では転送量やクエリコストが増大

適切なユースケース

全抽出が適しているケース

  • 初期データロード: 新規DWH構築時の初回データ投入
  • 小規模データセット: 数千〜数万件程度のマスタデータ
  • 更新頻度が低いデータ: 週次・月次で更新されるデータ
  • 履歴管理が不要なデータ: 常に最新状態だけが必要なケース

部分抽出(Incremental Load)とは

部分抽出(Incremental Load) とは、前回の抽出以降に追加・更新されたデータのみを抽出し、ターゲットシステムに転送する方式です。

変更検知の方法

部分抽出を実現するには、「どのデータが変更されたか」を検知する仕組みが必要です。

1. タイムスタンプ方式

最も一般的な方法です。テーブルにupdated_atカラムを用意し、前回抽出時刻以降のレコードを抽出します。

incremental_load_timestamp.sql
-- 前回抽出時刻以降に更新されたレコードを抽出
INSERT INTO target_table
SELECT *
FROM source_table
WHERE updated_at > @last_extracted_at;

2. CDC(Change Data Capture)方式

データベースのトランザクションログを監視し、INSERT/UPDATE/DELETEの変更をリアルタイムでキャプチャします。

代表的なCDCツール

  • Debezium: オープンソースのCDCプラットフォーム
  • AWS DMS: AWSのDatabase Migration Service
  • Fivetran / Airbyte: マネージドETLサービス

3. バージョン番号方式

レコードにバージョン番号を付与し、前回抽出時のバージョン以降を抽出します。

incremental_load_version.sql
-- 前回抽出バージョン以降のレコードを抽出
INSERT INTO target_table
SELECT *
FROM source_table
WHERE version > @last_extracted_version;

メリット

メリット 説明
処理時間が短い 差分データのみ処理するため高速
リソース効率が良い CPU・メモリ・ネットワーク使用量を大幅削減
コスト削減 クラウド環境での転送・処理コストを抑制
リアルタイム性 頻繁な更新(分単位・秒単位)に対応可能

デメリット

デメリット 説明
実装が複雑 変更検知ロジック、状態管理が必要
削除の検知が困難 物理削除されたレコードを検知できない場合がある
データ不整合リスク 変更検知の漏れにより不整合が発生する可能性

削除データの扱いに注意
部分抽出では、ソースで物理削除(DELETE)されたレコードを検知できない場合があります。対策として論理削除is_deletedフラグ)を採用するか、定期的に全抽出で整合性を確認することを推奨します。

適切なユースケース

部分抽出が適しているケース

  • 大規模データセット: 数百万〜数億件規模のトランザクションデータ
  • 高頻度更新: 日次・時間単位・リアルタイムでの更新が必要
  • ストリーミング処理: イベント駆動型のデータパイプライン
  • コスト最適化: クラウドリソースの使用量を抑えたい場合

比較表で見る違い

全抽出と部分抽出の特徴を一覧で比較します。

観点 全抽出(Full Load) 部分抽出(Incremental Load)
処理対象 データセット全体 新規・更新データのみ
処理速度 遅い(データ量に比例) 速い(差分量に依存)
リソース消費
実装難易度 低(シンプル) 高(変更検知が必要)
データ整合性 高(毎回同期) 中(不整合リスクあり)
削除の反映 ○(自動的に反映) △(工夫が必要)
コスト 高(大量転送) 低(差分転送)
更新頻度 週次・月次向き 日次・リアルタイム向き

実践での使い分け

判断フローチャート

どちらの方式を採用すべきか、以下のフローで判断できます。

ハイブリッドアプローチ

実務では、全抽出と部分抽出を組み合わせるハイブリッドアプローチが効果的です。

具体的なパターン

パターン 説明 適用例
日次部分 + 週次全 日次で差分を取り込み、週末に全抽出で整合性確認 トランザクションデータ
リアルタイムCDC + 日次全 CDCでストリーミング、日次で全抽出してデータ補完 在庫管理システム
テーブル別使い分け マスタは全抽出、トランザクションは部分抽出 多くのDWHプロジェクト
ハイブリッド実装のサンプルコード(Python)
hybrid_load_example.py
from datetime import datetime, timedelta

def load_data(table_name: str, load_type: str = "incremental"):
    """
    データロード関数
    
    Args:
        table_name: 対象テーブル名
        load_type: "full" または "incremental"
    """
    if load_type == "full":
        # 全抽出: テーブルを置換
        query = f"""
        CREATE OR REPLACE TABLE target.{table_name} AS
        SELECT * FROM source.{table_name}
        """
    else:
        # 部分抽出: 差分をMERGE
        last_loaded_at = get_last_loaded_timestamp(table_name)
        query = f"""
        MERGE INTO target.{table_name} AS t
        USING (
            SELECT * FROM source.{table_name}
            WHERE updated_at > '{last_loaded_at}'
        ) AS s
        ON t.id = s.id
        WHEN MATCHED THEN UPDATE SET *
        WHEN NOT MATCHED THEN INSERT *
        """
    
    execute_query(query)
    update_last_loaded_timestamp(table_name)

def run_daily_job():
    """日次ジョブ: 部分抽出"""
    for table in ["orders", "order_items", "payments"]:
        load_data(table, "incremental")

def run_weekly_job():
    """週次ジョブ: 全抽出で整合性確保"""
    for table in ["orders", "order_items", "payments"]:
        load_data(table, "full")

まとめ

要点の振り返り

方式 特徴 適したケース
全抽出 シンプル・高整合性 小規模データ、初期ロード、低頻度更新
部分抽出 高速・低コスト 大規模データ、高頻度更新、リアルタイム処理

選択のポイント

  1. データ量が小さく、シンプルさを優先 → 全抽出
  2. データ量が大きく、効率を優先 → 部分抽出
  3. 両方のメリットを享受したい → ハイブリッドアプローチ

2025年現在のベストプラクティス
大規模データパイプラインでは部分抽出をデフォルトとし、定期的な全抽出で整合性を担保するハイブリッドアプローチが推奨されています。

参考リンク

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?