見出し画像

Amazon QuickSightの落とし穴

概要

こんにちは!サーバーサイドエンジニアの真米です。

CircuitXのリプレイス作業の一部の画面で、「工数の削減」と「社内での新しい技術のナレッジを貯める」ことを目的に Amazon QuickSight (以下QuickSight)を使用しました。
QuickSightを導入を検討している方の技術選定の助けになればと思い、今回のリプレイス作業で苦労したポイントをまとめました。

また、リプレイス作業に関しては、2021年から少しずつ進めています。
過去に記事をいくつか出しておりますので、興味がございましたら読んで下さい!


事前知識

今回の記事で使用するQuickSight独自の用語と、実施したリプレイス作業の流れをざっくりと知っておくと、この記事が読みやすくなるかと思います。
(ご存知でしたら、読み飛ばして下さい。)

用語

  • データセット: DBに接続したテーブルやSQLを実行・表示するための環境

  • 分析: データセットで取得したデータを可視化する環境

  • ダッシュボード: 分析で作成したものを共有するための環境

  • SPICE(Super-fast, Parallel, In-memory Calculation Engine): インメモリエンジン。事前にインポートしたデータを「分析」で使用できるため、データを高速で取得できる

  • 計算フィールド: 「データセット」から得られた値を元に、追加の計算や判定を行う

  • コントロール: 分析で値をフィルタリングする

リプレイスの流れ

  1. 既存の実行しているコードから、QuickSightで実行できるようにSQLクエリを調整

  2. 「データセット」にSQLクエリを記述して、必要なデータを取得

  3. 「データセット」を「分析」で使用して、リプレイス前の画面に合わせてグラフや表などでデータを表示

  4. 「ダッシュボード」に「分析」で作成した内容を公開表示

  5. フロント側で埋め込む

AWS公式が上げている画像を見ると、イメージしやすいかと思います。

ワークフローの参考図
引用元: https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/how-quicksight-works.html

落とし穴①複雑なSQLクエリの処理が難しい

こちらは他のBIツールを使用する場合も当てはまると思いますが、今回最も苦労したポイントです。
QuickSightのタイムアウト要件は以下のどちらかの場合で起こります。

  • データの準備に 50 秒以上かかる

  • ビジュアルの生成に 2 分以上かかる

実行時間が長すぎるとタイムアウトエラーになる

リプレイス作業で、既存システムのSQLクエリをQuickSightに移行した際、JOINやUNION ALLを多用するクエリでタイムアウトが頻発しました。
これを解決するためには「SPICEを利用する」選択肢がありますが、SPICEの利用では次の問題点が出てきました。

  1. パラメータの利用制限: SPICEにデータをインポートすると、データセット内のSQLクエリで動的なパラメータを利用できない

  2. コストの増加: (パラメータ利用できないため)SPICEを使いデータセットから全データを取り出して絞り込む必要があり、コストが増加(SPICEは容量に応じた課金形態のため)

  3. 更新間隔の制限: SPICEのデータ更新は15分間隔が最小であり、最新データの取得に制約がある

今回は以下の2つの条件に当てはまるものはQuickSightではなく、スクラッチで実装するように対応方針を決めました。

  1. SQLクエリのパフォーマンスチューニングを行ってもタイムアウトする

  2. もともと実行していたクエリでパラメータを多く含むもの(SPICEのデータ量が増加してしまうため)

また、今回は行いませんでしたが、QuickSight用に別途データを読み込む用のテーブル作成なども対策として挙げられるかと思います。

落とし穴②計算フィールドの関数が充実していない

正規表現の文字列検証

例として、年月のパラメータを「yyyy-mm形式」で取ってくる際にチェックする計算フィールドを用意したいと思います。
計算フィールドで対応しようとすると、以下のようになります。
(今回は有効なものを「Valid Format」、無効なものを「Invalid Format」とだけ返しています。)

ifelse(
    Strlen(${YearMonth}) = 7 AND Substring(${YearMonth}, 5, 1) = '-',
    'Valid Format',
    'Invalid Format'
)

「全体の長さが7文字(yyyy-mm)」や「ハイフン(-)の位置が5文字目にくる」といったことは対処できていますが、「数値以外(aaaa-aa)」や「無効な 形式(0000-00)」などをチェックすることができません。
このように正規表現を用いた細かい制御などが出来ません。

配列やリスト内の特定の要素へのアクセス

配列やリストなどの形式で格納されたカラムに対する操作するための関数は特に用意されていません。
例えば、1つのカラム「ids」に「”1, 2, 3, 4, 10”」のような形式でデータが入っていた場合に、「2つ目の値のみを取り出して表示」といった操作ができません。

祝日の表示切替

こちらのユースケースや実装方法に関しては他のブログで紹介しておりますので、気になる方は読んでみて下さい。
Amazon QuickSightで日付を表示する際のTips

「isWorkDay()」を使用することで土日の判定を行えますが、祝日は判定できません。
行う場合は、祝日のリストを含む別のデータセットを用意して、判定ロジックを作成する必要があります。

落とし穴③表示周りの細かな制御が行えない

特定の条件での文字の非表示

条件によって値の表示・非表示は「値の色を背景色と同色にして隠す」ことで行えますが、通常のテキストは出来ません。
例として、以下のように「月毎の売上の値」と「昨日の売上の値」を表示するとします。
ただし、コントロールに指定された「年月」のデータを元に表示して、今月以外の場合は、「昨日の売上」を非表示にしたいと思います。
データセットで取ってきた値は、「条件付き書式設定」を用いることで、対応することができますが、文言の「昨日の売上」を非表示にすることはできません。

今月のデータ
前月のデータ
(「昨日の売上」のテキストが残ってしまう)

このようにパラメータや値によって、テキストを非表示にするといったことができません。

動的な値のハイパーリンク

データセットから取得した値によって、カラムごとにURLのパラメータの値を分析側で計算フィールドを用いることで行うことができます。

CONCAT('https://test.com/', toString({id}))

しかし、こちらを動的な値(例えばid列)にハイパーリンクを持たせるといったことができません。
別途URL表示する用の列を用意する必要があります。

別の列でURLを設定する必要がある

データセットから取得した値を用いたコントロールの値の並べ替え

データセットからとってきた場合は、コントロール値の並びは自動的に昇順になってしまいます。

データセットから取得してきた「年月」のデータの例

現在の年月に近い値を持ってきたいので降順にしたかったのですが、変更することは不可能でした。
(試しにデータセット側でORDER BYしてみましたが、変わらず昇順のまま表示されました。)

最後に

今回リプレイス作業時にQuickSightではまった点をまとめました。
個人的には、ドメイン周りへの細かな要件への対応が難しく、リプレイス作業との相性が良くなかった印象でした。
ただし、多様なグラフが用意されており、非エンジニアでも扱いやすいように直感的にわかりやすい作りとなっているため、細かな仕様がない社内分析ですぐ使いたい場合には向いているケースがあるように感じました。
また、2016年からとまだまだ新しいサービスで、2024/03現在でも徐々に機能が追加されているので今後より便利な機能が追加されることを期待しています。

最後に、一緒に作業していた旧負債解消チームの皆様(渋谷さん、栄さん、久野さん)ありがとうございました。
皆様が作業ログやドキュメントを細かく残してくださったおかげで、この記事をまとめることができました。

参考記事

この記事が気に入ったらサポートをしてみませんか?