Tableau Prep Builder のフロー実行が 遅い問題(データベース接続の場合) 解決編
前回記事では、データベース接続で Tableau Prep Builder (以下 "PREP") を使った場合、フロー実行が非常に遅くなるケースがあることを書きました。
では、どうしたらいいか? 解決編に入ります。
今回の例では、ファクトテーブル (ORDERS) が1億5000万行あり、これをローカルPCにダウンロードするのに時間がかかっていると思われます。そこでフローを見直し、先に集計をかけたらどうか?と考え、試してみました。新たに作成したフローは以下です。
前回とどこを変えたかというと、日付計算と集計を、結合より前に行うようにしました。理由は、CUSTOMER テーブルとの結合キーが CUSTKEY なので、先に年月とCUSTKEY で集計したほうが行数が少なくなると考えたから。結果はどうなったかと言うと …
SELECT
"N_NAME" AS "N_NAME",
"N_NATIONKEY" AS "N_NATIONKEY"
FROM "SFSALESSHARED_SFC_SAMPLES_SAMPLE_DATA"."TPCH_SF100"."NATION"
(実行時間: 1.5秒)
SELECT
"C_CUSTKEY" AS "C_CUSTKEY",
"C_NATIONKEY" AS "C_NATIONKEY"
FROM "SFSALESSHARED_SFC_SAMPLES_SAMPLE_DATA"."TPCH_SF100"."CUSTOMER"
(実行時間: 3.2秒)
SELECT
"O_CUSTKEY" AS "O_CUSTKEY",
SUM("O_TOTALPRICE") AS "O_TOTALPRICE",
CAST(DATE_TRUNC('MONTH',"O_ORDERDATE") AS DATE) AS "Year and Month"
FROM "SFSALESSHARED_SFC_SAMPLES_SAMPLE_DATA"."TPCH_SF100"."ORDERS"
GROUP BY 1, 3
(実行時間: 14秒)
3つ目の SQL を見て下さい。日付の計算(年月)と集計は、Snowflake側でやってくれた!
だが、結合はやってくれない。フロー実行時間は3分19秒、前回とあまり変わりませんでした。
しかし、ここで判ったことは、結合までは Snowflake側でやってくれること。少し光が見えました。
最初の集計結果の行数を確認すると1億3900万行。行数はあまり減っていませんでした。
そこで、集計を年に変えて再度テストしてみました。
前回フロー: 3分12秒
今回フロー: 1分24秒
かなり速くなった!
集計結果が6000万行に減ったことで、ローカルPCへの転送時間が減ったことによる効果でしょう。
結合前までは Snowflake側でクエリーを実行してくれること、先に集計することで行数が減らせるならば、実行時間を短縮できることが検証出来ました。
しかし、"PREP" が結合をデータベース側に指示してくれない問題は解決していません。そこで閃いたのは「カスタムSQLで先に結合をやってみたらどうか?」 "PREP" はデータベース接続の場合、カスタムSQLを書くことが出来ます。
今回は、以下のカスタムSQLを書きました。
ORDERS と CUSTOMER を結合してます。SELECT句はあえてワイルドカードにしてみました。
全体のフローはこうなりまります。
カスタムSQL で NATIONKEYは取得できているので、集計は年月と NATIONKEY で行っています。さて、フローの実行結果は?
なんと!10秒でフロー実行出来た!
(リザルトキャッシュは OFF で計測してます)
実行された SQL は以下でした。
SELECT
"N_NAME" AS "N_NAME",
"N_NATIONKEY" AS "N_NATIONKEY"
FROM "SFSALESSHARED_SFC_SAMPLES_SAMPLE_DATA"."TPCH_SF100"."NATION"
(実行時間: 5.8秒)
SELECT
"C_NATIONKEY" AS "C_NATIONKEY",
SUM("O_TOTALPRICE") AS "O_TOTALPRICE",
CAST(DATE_TRUNC('MONTH',"O_ORDERDATE") AS DATE) AS "Year and Month"
FROM (
SELECT *
FROM
TPCH_SF100.ORDERS
INNER JOIN TPCH_SF100.CUSTOMER
ON (O_CUSTKEY = C_CUSTKEY)
)
GROUP BY 1,3
(実行時間: 10秒)
今回も NATION テーブルの結合はやってくれませんでしたが、その前までは Snowflake側でクエリーを実行してくれました。年月と NATIONKEY での集計結果は 2000行ですので、ダウンロードも秒速で出来た、ということです。
"PREP" をデータベースに接続してフロー作成する場合は、注意が必要です。残念ながら結合はデータベース側でやってくれません。従って、結合前にいかにレコード数を少なくしておくかがパフォーマンス向上に繋がります。外部キー集計が必要ならば、あらかじめカスタムSQLで結合しておくのが良い。これによりデータベース側のパワーを最大限生かすことが出来ます。
3分半かかるクエリーを10秒で終わらせることが出来る、ということ。
カスタムSQLは、少し難しく感じられるかも知れませんが、結合だけならそんなに難しいものでもありません。是非、検討してみて下さい。
(そもそも "PREP"から結合を指示してくれればいいんですがね)
尚、今回のフローは、途中で列削除を行っていません。PREP側で出力内容を判断し発行するクエリーを最適化し、不要なフィールドは削除してくれているようです。列数が多いと、フロー作成中はプロファイリングに時間がかかってしまいますが、フロー実行中は最適化されるのでパフォーマンスにはあまり影響ないと言えます。
状況は、使用しているデータベースによって多少異なるかも知れません。データベース接続で "PREP" が遅い!と感じたら、是非、試してみてください。
(終わり)