はじめに
こんにちは、樋口と申します。
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 サービス) 間で同期させることができます。
これを使うと、外部の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で結合します。
- テーブル作成: 取得した2つのリストを、Collection内のテーブルとして定義します。
- 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 などを利用し 「本当に必要なカラムだけを取得する」 ように設計することが重要です。
さらに大量のデータを扱う場合
もし、上記の「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への置き換えを検討してみてください!
※記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。
