7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQL Collectionを使って大量データ同期処理のタスク数を節約をしてみた

Last updated at Posted at 2025-12-19

はじめに

こんにちは、樋口と申します。
NTT東日本 デジタル革新本部 デジタルデザイン部に所属しており、普段はWorkatoなどを活用して、社内の業務改善やシステム開発を行っています。

この記事は Workato Advent Calendar 2025 の 19日目の記事です。

数万件規模のOutSystemsで構築した社内システムのDBデータとEntra ID (旧Azure AD)間のデータ同期において、Workatoの「SQL Collection」機能を活用し、APIコール数を劇的に削減(タスク節約)した事例を紹介したいと思います。

抱えていた課題:数万件のN+1ループと90分の壁

今回直面したユースケースは以下のようなものでした。

  • 同期元: Entra ID (旧Azure AD)
  • 同期先: OutSystems (社内システム)
  • 要件: Entra ID上の属性情報を、社員番号をキーにしてOutSystems側のテーブルに同期したい
  • 対象: 全社員(数万レコード規模)

Before:愚直なアプローチ

通常のアプローチでレシピを作ると、以下のようなフローになります。

これを行うと、社員が1万人いれば、最低でも 1万回以上のAPIコール が発生します。
さらに深刻なのが 処理時間 です。Workatoの1ジョブあたりの実行時間は 最大90分 ※1という制限があります。数万件をループ処理していると確実にこの制限を超えてしまい、時にはタイムアウトエラーで処理が完遂しない という致命的な問題がありました。

※1: Workato Docs - Recipe jobs

解決策:SQL Collection by Workato

そこで採用したのが SQL Collection by Workato です。
簡単に言うと、「レシピの実行メモリ上に展開できる一時的なリレーショナルデータベース(中身はSQLite)」 です。

Collection by Workato は、テーブルデータを操作するためのツールを提供する堅牢なネイティブアプリケーションです。コレクションを使用すれば、関連データを複数のシステム (データベース、Web サービス) 間で同期させることができます。

引用元: Workato Docs - Collection by Workato

これを使うと、外部のDBを用意することなく、取得したリストデータに対して SQL(SELECT, JOIN, WHEREなど) を実行してデータを加工・抽出することができます。

実装アプローチ:メモリ上でデータを突き合わせる

今回実装したアプローチの基本は 「1件ずつ処理するのをやめ、リストごと取得してメモリ上でJOINする」 です。

※今回の実装例では、OutSystems、Entra IDともにデータ件数がSQL Collectionの上限である 50,000件に収まる 前提で構成しています。

全体フロー(After)

Step 1: データのリスト取得(Bulk Get)

まず、ループ処理の中でAPIを叩くのを回避するため、最初に両方のシステムから対象データをリストとして一括取得します。

  • Entra ID: 社員番号を持っているユーザー全件を取得
  • OutSystems: ID連携が必要なレコードを一括取得

この際、後述するメモリ制限を考慮し、APIで取得するカラム(フィールド)は必要なものだけに絞る ことが重要です。

Step 2: CollectionへのロードとSQL実行

取得した2つのリストをCollectionに「テーブル」としてロードし、SQLで結合します。

  1. テーブル作成: 取得した2つのリストを、Collection内のテーブルとして定義します。
  2. SQL実行: 以下のようなSQLを実行し、メモリ上でデータを結合します。
SELECT
  l.Id AS OS_Record_Id,
  r.User_UUID AS Entra_Id,
  r.Email_Address
FROM
  OutSystems_Users AS l
INNER JOIN
  EntraID_Users AS r
ON
  l.Employee_Number = r.employee_number

これにより、APIを何万回も叩くことなく、「OutSystemsに存在し、かつEntra IDにも存在する社員」 のペアを一瞬で突き止められます。

Step 3: 一括更新(Bulk Update)

SQLで抽出した結果をOutSystemsに書き戻します。
OutSystems側のBatch更新アクションの制約(1回あたり最大10,000行)に合わせ、SQLの結果リストをさらに 10,000件ずつの内部ループ に分割してリクエストを送信しています。

注意点とハマりどころ

実装時にいくつか気をつけるべき制約があります。

レコード数が50,000件を超える場合
Workatoの仕様上、SQL Collectionが保持できる最大レコード数は 50,000行 です。
対象データが50,000件を超える可能性がある場合は、50,000行ごとのバッチ分割をして処理するなどの工夫が必要になります。

2. 10MBのサイズリミットとカラム数の絞り込み
上記の通り、レコード数が50,000行以内であっても、Collection全体で 10MB というサイズ制限があります。
カラム数(列)が多すぎるとこの制限に抵触してしまうため、API取得の時点で Select Field などを利用し 「本当に必要なカラムだけを取得する」 ように設計することが重要です。

スクリーンショット 2025-12-12 8.58.29.png

さらに大量のデータを扱う場合
もし、上記の「50,000行/10MB」という制限を超えて、数GB単位のデータを扱いたい場合は、SQL Transformations コネクター という選択肢もあります。

こちらはSQL Collectionとは異なり、同一Job内のメモリ処理ではなく バックグラウンドでの非同期処理 として動作するため、非常に大規模なデータもパワフルに扱うことができます。 SQL Collectionの制限がボトルネックになる場合は、こちらの利用も検討してみると良いでしょう。

まとめ

Collection by Workatoを活用することで、以下のような成果が得られました。

項目 Before (For each) After (Collection)
APIコール数 数万回 数回 (リスト取得+更新のみ)
タスク消費 大量(数万Tasks/Job) 最小限 (数十Tasks/Job)
処理結果 数十分で完了~
タイムアウト(90分以上経過)
数分で完了

大量データの突き合わせや、「VLOOKUP的な処理」をレシピ内で行いたい場合、Collection機能は非常に強力な武器になります。
皆さんもぜひ、ループ処理でタスクが溶けているレシピがあれば、Collectionへの置き換えを検討してみてください!


※記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?