データ基盤再設計でレスポンス速度を 40倍高速化し、顧客体験を改善するまでの軌跡
はじめに
こんにちは、ダイニーのデータチームのエンジニアをしている kawamitsu です。
ダイニーでは飲食店さま向けのデータ分析プロダクトを提供しています。
本記事では、膨大な店舗データの処理によるアプリケーションのボトルネックを、データ基盤によって解決した事例を紹介します。
先に成果を説明しますが、データ基盤の再設計によりユーザーのデータ分析においてタイムアウトのほぼ全廃と全店舗・任意期間のデータ取得を可能にしました。
この記事を通して、データエンジニアリング × アプリケーションエンジニアリング の開発に少しでも興味を持っていただけたら幸いです。
背景:飲食店におけるデータ活用の重要性
飲食店の経営において、データの活用は重要な経営判断の基盤となります。
注文履歴、決済履歴、監査目的の会計取消・修正履歴など、多岐にわたる情報を、全店舗分まとめていつでもアクセスできる環境が求められています。
このようなニーズに応えるには、単なる集計にとどまらず、柔軟かつ高品質なデータプロダクトとしての設計が不可欠です。
ダイニーでは、レジ・ハンディ・モバイルオーダー・キッチンプリンタなど、飲食店の運営に必要なプロダクトをすべて自社開発しており、それに伴って膨大な一次データを保有しています。
これらのデータを、顧客が必要とする粒度・タイミングで柔軟に提供できる環境を整えることが、ダイニーのデータエンジニアリングに求められる役割です。
元々の課題:集計処理がボトルネックに
当初、分析アプリケーションでは、ユーザーが定期的にアクセスする必要のあるデータに対し、その都度ローデータを元にバックエンド側で集計処理を実行していました。
つまり、データの再利用性や事前集計といった考慮がされておらず、データ基盤が未整備の状態だったのです。
この構成では、各クライアントのリクエストに対して毎回以下のような処理が行われていました。
- 注文・決済・会計取消しなどの複数ソースからのデータ取得
- ORMによるリレーション解決
- JavaScript(TypeScript)ベースのアプリケーションロジックによる手続き的集計
その結果として、企業規模が大きくなればなるほどレスポンス時間が増加し、以下のような問題が顕在化していました。
- 集計期間を制限せざるを得ない(それ以上だと処理がタイムアウトしてしまうため)
- 店舗ごとの個別リクエストが必要となり、「全店舗まとめて確認する」といった本来やりたいことができない
- 利用者側に「期間を絞ってください」「店舗を分けてください」と依頼するなど、プロダクト側で本来担うべき負担をユーザーに転嫁してしまう
これらは、パフォーマンスだけでなくUXの観点からも深刻な課題であり、根本的な構造改革が求められる状況でした。
アプローチ:データ基盤化による最適化
1. 既存集計ロジックの整理
まず最初に行ったのは、既存のバックエンド集計処理の読み解きです。アプリケーションは TypeScript / GraphQL を用いて構築されており、各データソースに対する集計ロジックがコードベースで実装されていました。
たとえば以下のようなドメイン固有の判断が存在しており、単純なSQLへの変換では意図を損なう可能性がありました。
- 注文キャンセルを集計に含める or 除外するか
- 会計取消しの扱い(財務帳票では必要なケースもある)
- 集計単位がサービス提供時刻ベースなのか会計時刻ベースなのか
2. データ基盤上での再設計と実装
アプリケーションの集計処理を正確に理解した上で、それを Dataform を利用してデータマートとして再設計しました。具体的には以下のプロセスで実装を行いました。
2.1 従来構成からの脱却
まず、以下のような「都度集計する旧構成」から、再利用可能な「事前集計基盤」への移行が目的でした。
都度集計する旧構成
データ基盤化した新構成
2.2 Dataform モデルによる分割設計
次に、TypeScript のアプリケーションコードを読んだ上でその内容を Dataform を使ってデータマートの実装を行います。
ダイニーでは責務単位のモデルを連結する形でデータマートを構成しています。
具体的には以下のような階層構造で構築しています。
- raw layer: RDB上のローデータをそのまま取り込むレイヤー
- staging layer: 日付処理, 重複排除などの前処理を行うレイヤー
- warehouse layer: 特定のドメインロジックを考慮してモデリングするレイヤー
- mart layer: 特定のユースケースに合わせて取り出すことを想定して構築するレイヤー
この階層構造に従って、各データマートの構築を進めました。
2.3 ユースケースを意識したテーブル設計
それぞれのモデルは、API経由で使いやすいように、シンプルで結合不要な構造になるように意識しました。
たとえば「売上サマリ」は各種APIやダッシュボードから参照されることを想定しており、shopId
, businessDate
, totalSales
のような単純な形に整えています。
このようにモデルを役割ベースで分割することで、属人化を防ぎつつ、運用や差分検証も容易になりました。
3. 精度検証とリスクマネジメント:差分が許されないデータに対して
本プロジェクトでは、出力されるデータが財務報告や経営指標として活用される重要なものであるため、出力結果の差分はインシデント級のリスクとなり得ます。
そこで以下のようなステップで慎重に精度検証を行いました。
✅ 差分検証のプロセス
- 既存のAPIを複数のクライアント環境でリクエストし、JSONデータを取得
- 新しいDataformベースのモデルから同様の期間・条件でデータを抽出
- 両者のデータをファイル出力し、レコード単位で突合
この比較には diffツールなどを活用し、自動化とスピードも意識しました。
さらに、一部のクライアントに対しては新旧の出力を併用する 段階的なリリース(canary deployment) を行い、安全性を確認しながらロールアウトしています。
リリースによるインパクト
データ基盤の再設計を経てリリースされた新構成は、単なる「構造改善」にとどまらず、実際のユーザー体験と業務効率に大きなインパクトがありました。
平均応答速度が 1 / 40 以下に
以下はとある店舗様20店舗の2025年4月分の日別売上のCSVダウンロードにおけるDevToolsの比較になります。
📉 Before: 平均40秒以上
📈 After: 平均1秒未満
新構成で事前に集計済みのデータを参照することで、平均応答時間が1s未満になりました。
タイムアウトのほぼ全廃
- 旧構成では、一定期間以上のリクエストでHTTP 504 エラー(タイムアウト)が頻発
- 新構成では、全件取得でも数秒で完了するため、タイムアウトゼロ運用を実現
全店舗・任意期間のデータ取得が可能に
- 以前は「期間を1ヶ月以内にしてください」「店舗を1店舗ずつ選んでください」といった制限が多く、UXの障害になっていました
- 新構成では集計対象の広さによる制限を排除し、本来の業務ニーズ(全体把握)に応えることが可能になりました
最後に
今回はデータエンジニアリングによってアプリケーションの顧客体験とデータの可用性を大幅に改善する実例を紹介いたしました。
データエンジニアリングが顧客体験の改善に直接寄与するケースの一例として、少しでもイメージがついたら幸いです。
ダイニーのデータチームではこのように、データエンジニアリングとアプリケーションエンジニアリングの境界を必要以上に分けずに、データによる顧客の価値の最大化に引き続きコミットしていきます。
少しでも興味のある方はぜひ一度お話ししましょう!
Discussion