QuickSight の SPICE 増分更新の挙動をイメージ図付きで解説します
コーヒーが好きな emi です。
QuickSight の SPICE 増分更新の挙動はやや癖があり、理解に時間を要しましたので、イメージ図付きでガッツリ解説します。
そもそも SPICE とは、というところは以下のブログの SPICE(スパイス) 部分を参照いただけますと幸いです。
最初にまとめ
- A. 日本時間 JST でSPICE 増分更新をした際の増分更新の範囲は以下
-
- JST ⇒ UTC に変換して - 9 時間
-
-
- から「頻度」に設定した時間をマイナス
- 「毎日」なら - 24 時間、「毎時」なら - 1 時間、など
-
-
-
- からウィンドウサイズに指定した時間をマイナス
- 「ウィンドウサイズ 1 時間」なら - 1 時間、「ウィンドウサイズ 12 時時」なら - 12 時間、など
-
-
▼頻度:毎日、ウィンドウサイズ:1 時間、0:30 JST に SPICE 増分更新を設定した場合のイメージ
-
B. 一度 SPICE 増分更新スケジュールを削除して、日を置いて再度 SPICE 増分更新スケジュールを設定すると、増分更新の設定に関わらず、前回の最後の SPICE 増分更新で取り込んだ時間から現在の時刻までのデータが全部 SPICE に取り込まれる。その後、 SPICE 増分更新が設定した頻度で開始される
-
C. SPICE 増分更新のウィンドウサイズを変更すると、まずフル更新が走り、その後 SPICE 増分更新が設定した頻度で開始される
- 「今すぐ更新」で SPICE 増分更新のウィンドウサイズを変更すると、既存の SPICE 増分更新スケジュールのウィンドウサイズも変更される
▼「今すぐ更新」で SPICE 増分更新のウィンドウサイズを 1⇒12 時間に変更した場合のイメージ
- D. ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」すると、前回の更新時点から現時点までのレコードが取り込まれる
- つまり、SPICE 増分更新のウィンドウサイズを変更しなければ、フル更新は走らず、SPICE 増分更新で設定した通りにスケジュールされる
▼ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」した場合のイメージ
- E. SPICE 増分更新のスケジュールの頻度のみを変更する際は必ず未来日付を指定する必要があり、変更保存後もフル更新は走らない
- 指定した未来日付から設定した頻度でスケジュール実行される
- 頻度を変更した 1 回目の SPICE 増分更新は、前回の取り込み範囲の後から漏れなく取り込むよう範囲指定される
▼ SPICE 増分更新スケジュールで頻度のみを変えた場合のイメージ
挙動確認
事前準備
まず、S3 バケットへのデータ配置、Athena テーブル作成、データセット・分析・ダッシュボード作成を行います。
事前準備手順は以下トグルを展開して確認ください。本記事の本題ではないのでトグルにたたんでいます。
S3 バケットへのデータ配置、Athena テーブル作成、データセット・分析・ダッシュボード作成
S3 バケットに置く CSV ファイル
ある会社でお菓子を食べたり持ってきて補充するデータです。お菓子を食べたらごきげんになったり、お菓子が無くて不調になったりする会社をイメージしました。
datetime,department,section,status,chocolate,donut,osenbei
2024-10-16 17:00:00.000,コンピューティング部,EC2課,不調,19,1,20
2024-10-16 17:00:00.000,コンピューティング部,Lambda課,不調,12,4,22
2024-10-16 17:00:00.000,コンピューティング部,Lightsail課,不調,13,3,24
2024-10-16 17:00:00.000,ストレージ部,EFS課,超ごきげん,18,7,29
2024-10-16 17:00:00.000,ストレージ部,FSx課,ごきげん,18,1,24
2024-10-16 17:00:00.000,ストレージ部,S3課,不調,15,2,20
2024-10-16 17:00:00.000,データベース部,RDS課,普通,14,2,28
2024-10-16 17:00:00.000,データベース部,DocumentDB課,不調,19,7,29
2024-10-16 17:00:00.000,データベース部,DynamoDB課,超ごきげん,11,2,24
CSV のひな形は生成 AI に生成してもらって、自分でいくつか数字やステータスを変更しました。
生成したモデルは GPT-4o です。ちなみにプロンプトはこちらです。
AWS株式会社は以下のような組織構造を持っています。
- コンピューティング部
- EC2課
- Lambda課
- Lightsail課
- ストレージ部
- EFS課
- FSx課
- S3課
- データベース部
- RDS課
- DocumentDB課
- DynamoDB課
それぞれの課は時間帯によって以下のステータスを持ちます。
- 超ごきげん
- ごきげん
- 普通
- 不調
それぞれの課に所属する人はお菓子を食べたり持ってきたりします。お菓子の種類は以下の通りです。
- チョコレート
- ドーナツ
- おせんべい
日時, 部署名, 課名, ステータス, チョコレートの個数, ドーナツの個数, おせんべいの個数 が記載された CSV ファイルを作成してください。
カラム名は `datetime`, `department`, `section`, `status`, `chocolate`, `donut`, `osenbei` としてください。
日時の形式は `YYYY-MM-DD HH:MM:SS` で date 型としてください。
S3 のパス構成は以下のようになっています。/jst/
の後ろの日付パスを Athena の Partition Projection(パーティション射影)で自動認識させます。
s3://<S3 バケット名>/sweets_with_status/jst/2024/10/16/17/1700_sweets_with_status.csv
Athena テーブルの作成
CREATE EXTERNAL TABLE IF NOT EXISTS `spiceincrementalupdatedb`.`sweets_with_status` (
`datetime` timestamp,
`department` string,
`section` string,
`status` string,
`chocolate` int,
`donut` int,
`osenbei` int
)
PARTITIONED BY (
`partition_date` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim' = ',',
'skip.header.line.count' = '1'
)
LOCATION 's3://<S3 バケット名>/sweets_with_status/jst/'
TBLPROPERTIES (
'classification' = 'csv',
'projection.enabled' = 'true',
'projection.partition_date.type' = 'date',
'projection.partition_date.format' = 'yyyy/MM/dd/HH',
'projection.partition_date.range' = '2024/10/15/00,NOW+9HOURS',
'projection.partition_date.interval' = '1',
'projection.partition_date.interval.unit' = 'HOURS',
'storage.location.template' = 's3://<S3 バケット名>/sweets_with_status/jst/${partition_date}'
);
データセット、分析、ダッシュボードの作成
データソースに Athena を選択してカスタム SQL クエリを作成します。
ドーナツの個数とステータスを取得するクエリです。
SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section
クエリモードは SPICE を選択し、「保存して公開」で分析を作成します。
分析では日ごとのドーナツの個数と、日ごとのステータスをビジュアルで可視化します。「公開」をクリックしてダッシュボードも保存します。
以上で準備完了です。
===事前準備ここまで===
SPICE 増分更新の設定
データセットの詳細を開き、更新タブで「新しいスケジュールの追加」をクリックします。
- 増分更新
- タイムゾーン:Asia/Tokyo (UTC+09:00)
- 開始時刻:2024/10/16 11:20 午後(いかにブログを下書きで眠らせていたかバレてしまいますね)
- 頻度:毎時
と設定し「増分更新を設定」をクリックします。
増分更新の設定が開きますので設定します。今回は以下のように設定しました。
- 日付の列:formatted_date(データセット作成時のカスタム SQL クエリで作成した日付列)
- ウィンドウサイズ(数値):1
- ウィンドウサイズ(単位):時間
ちなみに、データ自身が日付列を持ってないと SPICE 増分更新はできません。以下ブログも参照ください。
「更新スケジュールの編集」に戻りますので、「保存」します。
保存すると、最初の更新が走り始めます。
SPICE 増分更新スケジュール設定直後の更新はフル更新か、増分更新か?
ここで問題です。
さて、増分更新スケジュールを一番最初に設定したときに走るこの更新は増分更新でしょうか。それともフル更新でしょうか。
履歴を見ると更新時間は「2024/10/16 23:20」、更新の種類は「手動、編集」となっています。スケジュールを設定したり変更したりした際は「手動、編集」と表示されるようです。
完了しました。
QuickSight 側の更新が完了したら、Athena でクエリの履歴を確認します。
内部的には、QuickSight が Athena で経由 SPICE に取り込むクエリを発行しています。
Athena の「最近のクエリ」タブで /* QuickSight xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx */
から始まるものが該当します。
2024/10/16 23:20
に実行された「手動、編集」のクエリに該当するクエリは Athena の履歴を開くと以下のようになっていました。
/* QuickSight d9db2f74-399d-4980-958a-70e08703c28b */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
これは フル更新クエリ です。
増分更新クエリだと where
句で時刻範囲が指定されるのですが、この SQL 文には時刻指定範囲がありません。
A. 日本時間 JST でSPICE 増分更新をした際の増分更新の範囲を調べる
スケジュールされた増分更新が実行される(1 回目)
さて、増分更新スケジュールが走る前に S3 バケットにいくつかデータを足しておきました。増分更新が走るのを待ちます。
はい、2024/10/16 23:30 に実行されました。
ダッシュボードの方も更新されています。
ダッシュボードの見え方調整
一部ダッシュボードの見え方が気に入らなかったので調整します。ブログの本筋とは関係ないので飛ばして大丈夫です。
Status の折れ線グラフが日単位になっていたのでデータが増えても変わっていませんでした。そのため分単位に変えます。
formatted_date
の集計を分単位に変えます。
形式を yyyy/mm/dd hh:mm
にします。
折れ線グラフの見え方が変わりました。これで OK です。
===ダッシュボード調整ここまで===
Athena で QuickSight から実行されたクエリを確認します。時刻で該当のクエリを確認できます。
開くと以下のようになっていました。
▼ 2024/10/16 23:30 実行クエリ
/* QuickSight cad73016-324c-409c-95dc-522ad5ab66f3 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729084842045 as varchar), 1, 10) AS bigint))
クエリの最後の行を見ると、Athena は以下のような where
句で、SPICE に取り込むデータの範囲を指定しています。
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729084842045 as varchar), 1, 10) AS bigint))
from_unixtime
から始まる時刻は、以下のクエリで何時か確認することができます。
select from_unixtime(cast(substr(cast(1729084842045 as varchar), 1, 10) AS bigint))
結果は 2024-10-16 13:20:42.000
となりました。
つまり、日付列が 2024-10-16 13:20
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
ここで、この日付は JST とか UTC とかの意味を失っていて、QuickSight は formatted_date
列の日付数字で SPICE に取り込むかどうかを判断しているという点がポイントです。
前回の更新時間との差 | ||
---|---|---|
スケジュール設定時のフル更新時間 | 2024/10/16 23:20 | 基準 |
増分更新実行時間 | 2024/10/16 23:30 | |
~より新しい時刻のデータを取り込む | 2024-10-16 13:20 | -10 時間 |
初回の更新時間との差を考えます。
- JST ⇒ UTC に変換して - 9 時間
- から「頻度」に設定した時間をマイナス
- 「毎時」なので - 1 時間の予定だが、まだ増分更新 1 回目なので換算しない⇒ 0 時間
- からウィンドウサイズに指定した時間をマイナス
- 「ウィンドウサイズ 1 時間」なら - 1 時間
- 前回の更新時間との差:10 時間
このように考えればつじつまが合います。
スケジュールされた増分更新が実行される(2 回目)
同様に二回目の増分更新も見ていきます。
▼ 2024/10/17 0:30 更新クエリ
/* QuickSight daa50094-8cec-4e74-9e32-21d09bf8a934 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729085403149 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1729085403149 as varchar), 1, 10) AS bigint))
実行結果:2024-10-16 13:30:03.000
つまり、日付列が 2024-10-16 13:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
増分更新実行時間 | 2024/10/17 0:30 | |
~より新しい時刻のデータを取り込む | 2024-10-16 13:30 | -11 時間 |
初回の更新時間との差を考えます。
- JST ⇒ UTC に変換して - 9 時間
- から「頻度」に設定した時間をマイナス
- 「毎時」なので - 1 時間
- からウィンドウサイズに指定した時間をマイナス
- 「ウィンドウサイズ 1 時間」なら - 1 時間
- 前回の更新時間との差:11 時間
スケジュールされた増分更新が実行される(3 回目)
三回目の増分更新も見ていきます。
▼ 2024/10/17 1:30 更新クエリ
/* QuickSight fe049a49-8eae-48c7-b8ad-ebab724e4977 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729089002850 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1729089002850 as varchar), 1, 10) AS bigint))
実行結果:2024-10-16 14:30:02.000
つまり、日付列が 2024-10-16 14:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
増分更新実行時間 | 2024/10/17 1:30 | |
~より新しい時刻のデータを取り込む | 2024-10-16 14:30 | -11 時間 |
初回の更新時間との差を考えます。
- JST ⇒ UTC に変換して - 9 時間
- から「頻度」に設定した時間をマイナス
- 「毎時」なので - 1 時間
- からウィンドウサイズに指定した時間をマイナス
- 「ウィンドウサイズ 1 時間」なら - 1 時間
- 前回の更新時間との差:11 時間
スケジュールされた増分更新が実行される(3 回目)
四回目の増分更新も見ていきます。
▼ 2024/10/17 2:30 更新クエリ
/* QuickSight 376abcf4-6ff2-4f36-96bc-2ffc4e237607 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729092602768 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1729092602768 as varchar), 1, 10) AS bigint))
実行結果:2024-10-16 15:30:02.000
つまり、日付列が 2024-10-16 15:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
増分更新実行時間 | 2024/10/17 2:30 | |
~より新しい時刻のデータを取り込む | 2024-10-16 15:30 | -11 時間 |
もう分かってきましたね。
A. 結果:日本時間 JST でSPICE 増分更新をした際の増分更新の範囲
結果をまとめると以下になります。
- 日本時間 JST でSPICE 増分更新をした際の増分更新の範囲は以下
-
- JST ⇒ UTC に変換して - 9 時間
-
-
- から「頻度」に設定した時間をマイナス
- 「毎日」なら - 24 時間、「毎時」なら - 1 時間、など
-
-
-
- からウィンドウサイズに指定した時間をマイナス
- 「ウィンドウサイズ 1 時間」なら - 1 時間、「ウィンドウサイズ 12 時時」なら - 12 時間、など
-
-
▼頻度:毎日、ウィンドウサイズ:1 時間、0:30 JST に SPICE 増分更新を設定した場合のイメージ
B. 一度 SPICE 増分更新スケジュールを削除して、日を置いて再度 SPICE 増分更新スケジュールを設定したときの挙動を調べる
増分更新ジョブは一時停止などができないため、スケジュールされた増分更新を止めるには削除するしかありません。スケジュールから「削除」します。
~~~~~~~~~~~~~~~~~~~~
~~ここで数日、時が流れます~~
~~~~~~~~~~~~~~~~~~~~
数日後、再度 SPICE 増分更新の検証をしたくなった私は、また同じ設定(頻度:1 時間、ウィンドウサイズ:1 時間)で増分更新の設定を行いました。
初回の増分更新が完了しました。本当の本当に一番最初に増分更新を設定した際はフル更新が走ったのですが、今回はいきなり「スケジュール済み、増分更新」となりました。
Athena 側で増分更新クエリを確認します。
▼ 2024/10/30 21:30 実行クエリ
/* QuickSight 765fb68c-3306-4188-ae25-e775a528360a */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1729096202907 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1729096202907 as varchar), 1, 10) AS bigint))
実行結果:2024-10-16 16:30:02.000
つまり、日付列が 2024-10-16 16:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
スケジュール削除前の最後の増分更新(~より新しい時刻のデータを取り込む) | 2024-10-16 15:30 | 基準 |
増分更新実行時間 | 2024/10/30 21:30 | |
~より新しい時刻のデータを取り込む | 2024-10-16 16:30 | 14 日以上前 |
前回の更新時間との差を考えると、スケジュールした増分更新を削除する前、最後に実行された増分更新の 1 時間後からデータを取り込もうとしています。
増分更新スケジュールを削除する直前に行われた 2024/10/17 2:30 の更新クエリでは、日付列が 2024-10-16 15:30
より新しいデータを取得していました。おそらく頻度が 1 時間なので 1 時間間が空いたのではと予想します。
B. 結果:一度 SPICE 増分更新スケジュールを削除して、日を置いて再度 SPICE 増分更新スケジュールを設定したときの挙動
結果をまとめると以下になります。
- 一度 SPICE 増分更新スケジュールを削除して、日を置いて再度 SPICE 増分更新スケジュールを設定すると、増分更新の設定に関わらず、前回の最後の SPICE 増分更新で取り込んだ時間から現在の時刻までのデータが全部 SPICE に取り込まれる。その後、 SPICE 増分更新が設定した頻度で開始される
C. SPICE 増分更新のウィンドウサイズを変更
SPICE 増分更新のウィンドウサイズを変更するとどうなるのかやってみます。まずは自動更新の結果を見ます。
まずは増分更新頻度:1 時間、ウィンドウサイズ:1 時間で走っているスケジュールされた自動増分更新を確認します。
▼ 2024/10/30 23:30 実行クエリ
/* QuickSight 9ba5e1e0-43e1-45a2-af3e-82b587d9a457 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730291440976 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730291440976 as varchar), 1, 10) AS bigint))
実行結果:2024-10-30 12:30:40.000
つまり、日付列が 2024-10-30 12:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
ウィンドウサイズを 1⇒12 時間に変更
ではウィンドウサイズを変更します。「今すぐ更新」からウィンドウサイズを変更します。
「増分プロパティの設定」
ウィンドウサイズを 12 時間にします。
続行します。
すると、「更新の確認」のポップアップが出て「今すぐ更新を開始してもよろしいですか?」と聞かれている裏で。ないにゃら更新が走っていることが分かりました。まだ「更新」は押下していません。
更新の種類は「手動、編集」となっています。
ここで初めて「更新」を押下します。
さて、履歴には更新が 2 行追加されました。裏で勝手に走った「手動、編集」と、「更新」を押下して初めて走った「手動、増分更新」の 2 行です。
終わりました。
Athena 側でクエリを確認していきます。まずは裏で勝手に走った「手動、編集」に該当する 2024/10/30 23:53 のクエリから見ます。
▼ 2024/10/30 23:53 に手動で増分更新しようとしたら裏で勝手に走ったクエリ(手動、編集)
/* QuickSight 46538fed-c2d4-4a46-b4ac-1b06b5517567 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
おや。これは where
句で時間範囲が指定されていません。フル更新です。
次に、「更新」を押下して実行した 2024/10/30 23:54 の増分更新クエリを確認します。
▼ 2024/10/30 23:54 実行クエリ(手動、増分更新)(毎時、ウィンドウサイズ12時間)
/* QuickSight 3f021d47-b1a6-4938-bfd6-5c8c9123c569 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730256792880 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730256792880 as varchar), 1, 10) AS bigint))
実行結果:2024-10-30 02:53:12.000
つまり、日付列が 2024-10-30 02:53
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
前回のスケジュール増分更新(~より新しい時刻のデータを取り込む) | 2024-10-30 12:30 | |
勝手に走ったフル更新実行時間 | 2024/10/30 23:53 | |
増分更新実行時間 | 2024/10/30 23:54 | |
~より新しい時刻のデータを取り込む | 2024-10-30 02:53 |
前回の更新時間との差を考えると、
-
- 増分更新実行時間 2024/10/30 23:54 JST ⇒ UTC に変換(- 9 時間)すると 2024/10/30 14:54
-
-
- から頻度:1 時間をマイナスするところだが、手動のため換算しない
-
-
-
- からウィンドウサイズ:12 時間をマイナスして 2024-10-30 02:53
-
ということになります。
ウィンドウサイズ変更後のスケジュールされた自動増分更新(1 回目)
ではこの後のスケジュールされた自動増分更新も見てみます。
▼ 2024/10/31 0:30 実行クエリ
/* QuickSight 27b55df2-7405-4004-80f1-6319b2fb7a21 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730256858675 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730256858675 as varchar), 1, 10) AS bigint))
実行結果:2024-10-30 02:54:18.000
つまり、日付列が 2024-10-30 02:54
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
手動の増分更新で取得した時間範囲とほぼ同じです。
ウィンドウサイズ変更後のスケジュールされた自動増分更新(2 回目)
▼ 2024/10/31 1:30 実行クエリ
/* QuickSight cf7f54aa-4f9e-4f5d-8cb8-3690b0f10480 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730259040895 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730259040895 as varchar), 1, 10) AS bigint))
実行結果:2024-10-30 03:30:40.000
つまり、日付列が 2024-10-30 03:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
前回の更新時間との差 | ||
---|---|---|
増分更新実行時間 | 2024/10/31 1:30 | |
~より新しい時刻のデータを取り込む | 2024-10-30 03:30 | -22 時間 |
前回の更新時間との差を考えます。
- 2024/10/31 1:30 JST ⇒ UTC に変換(- 9 時間)して 2024/10/30 16:30 UTC
- 頻度:1 時間をマイナスして 2024/10/30 15:30
- ウィンドウサイズ:12 時間をマイナスして 2024-10-30 03:30
- 前回の更新時間との差:22 時間
なるほど、「今すぐ更新」からウィンドウサイズを変更した場合、スケジュールされた自動増分更新のウィンドウサイズも変更されるということですね。
ウィンドウサイズ変更後のスケジュールされた自動増分更新(3 回目)
▼ 2024/10/31 2:30 実行クエリ
/* QuickSight d3cf3077-f329-4f29-8794-6efd8625d6e7 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730262641209 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730262641209 as varchar), 1, 10) AS bigint))
実行結果:2024-10-30 04:30:41.000
つまり、日付列が 2024-10-30 04:30
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
C. 結果:SPICE 増分更新のウィンドウサイズを変更すると、まずフル更新が走り、その後 SPICE 増分更新が設定した頻度で開始される
結果をまとめると以下になります。
- SPICE 増分更新のウィンドウサイズを変更すると、まずフル更新が走り、その後 SPICE 増分更新が設定した頻度で開始される
- 「今すぐ更新」で SPICE 増分更新のウィンドウサイズを変更すると、既存の SPICE 増分更新スケジュールのウィンドウサイズも変更される
▼「今すぐ更新」で SPICE 増分更新のウィンドウサイズを 1⇒12 時間に変更した場合のイメージ
D. ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」する
では、ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」するとどうなるか試します。
まずはスケジュールされた自動増分更新の結果を確認しておきます。
▼ 2024/10/31 21:40 実行クエリ(スケジュールされた自動増分更新)
/* QuickSight c9a6f918-c910-4ffc-a874-df7298d0a5c9 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730371247250 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730371247250 as varchar), 1, 10) AS bigint))
実行結果:2024-10-31 10:40:47.000
つまり、日付列が 2024-10-31 10:40
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
「今すぐ実行」でウィンドウサイズを変えずに増分更新する
では「今すぐ実行」で増分更新します。
▼ 2024/10/31 22:17 に「今すぐ実行」で増分クエリを実行する
/* QuickSight 39d68cd8-b247-4bc2-8358-f1192452143d */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730374847561 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730374847561 as varchar), 1, 10) AS bigint))
実行結果:2024-10-31 11:40:47.000
つまり、日付列が 2024-10-31 11:40
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
この時、特に裏でフル更新が走ると言ったことはありませんでした。
「今すぐ実行」の後のスケジュールされた自動増分更新
さて、この後のスケジュールされた自動増分更新を確認します。
▼ 2024/10/31 22:40 実行クエリ
/* QuickSight 381bff2f-85da-4967-a3a0-71baba06007d */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1730377042192 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1730377042192 as varchar), 1, 10) AS bigint))
実行結果:2024-10-31 12:17:22.000
つまり、日付列が 2024-10-31 12:17
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
「今すぐ実行」で実行した増分更新の時間より新しいデータを取り込もうとしていることが分かりました。
D. 結果:ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」すると、前回の更新時点から現時点までのレコードが取り込まれる
結果をまとめると以下になります。
- ウィンドウサイズを変えずに SPICE 増分更新を「今すぐ更新(手動更新)」すると、前回の更新時点から現時点までのレコードが取り込まれる
- つまり、SPICE 増分更新のウィンドウサイズを変更しなければ、フル更新は走らず、SPICE 増分更新で設定した通りにスケジュールされる
- つまり、SPICE 増分更新のウィンドウサイズを変更しなければ、フル更新は走らず、SPICE 増分更新で設定した通りにスケジュールされる
E. SPICE 増分更新のスケジュールの頻度を変更する
では最後に SPICE 増分更新のスケジュールの頻度を変更してみます。
「更新スケジュールの編集」で頻度を変える際は以下のように未来日付を入力するよう注意されます。
ちなみに SPICE 増分更新では以下の頻度が選べます。
- 15 分ごと
- 30 分ごと
- 毎時
- 毎日
- 毎週
- 毎月
他の増分更新の設定はそのままで続行します。
開始日付を未来日付にして保存します。
保存できました。増分更新が走るのを待ちます。
30 分毎に増分更新が実行されているのが分かりました。裏でフル更新が走ることはないようです。
頻度変更前のクエリの実行結果
まずは頻度変更前のクエリの実行結果を確認します。
▼ 2024/11/10 19:35 実行クエリ(頻度:1 時間)
/* QuickSight 8da46374-3f89-4ca3-9616-0c4586255c34 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1731227741599 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1731227741599 as varchar), 1, 10) AS bigint))
実行結果:2024-11-10 08:35:41.000
つまり、日付列が 2024-11-10 08:35
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
頻度変更後のスケジュールされた自動増分更新(1 回目)
▼ 2024/11/10 20:15 実行クエリ(スケジュール済み、増分更新)
/* QuickSight 7132442a-42bc-4cc9-a912-c78137a45358 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1731231341217 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1731231341217 as varchar), 1, 10) AS bigint))
実行結果:2024-11-10 09:35:41.000
つまり、日付列が 2024-11-10 09:35
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
-
- 2024/11/10 20:15JST⇒2024/11/10 11:15UTC
-
- 2024/11/10 11:15⇒頻度30分⇒2024/11/10 10:45
-
- 2024/11/10 10:45⇒ウィンドウサイズ1時間⇒2024/11/10 09:45
おや。計算があいません。ちょっと理由は分からなかったのですが、前回更新分から漏れることはないので一旦このまま次の更新クエリも確認します。
頻度変更後のスケジュールされた自動増分更新(2 回目)
▼ 2024/11/10 20:45 JST 実行クエリ
/* QuickSight 67ab33be-7ff4-43e3-94bb-7252a23058c4 */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1731233723708 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1731233723708 as varchar), 1, 10) AS bigint))
実行結果:2024-11-10 10:15:23.000
つまり、日付列が 2024-11-10 10:15
より新しいデータを取得するよ、という意味の増分更新クエリであることが分かります。
-
- 2024/11/10 20:45 JST⇒2024/11/10 11:45 UTC
-
- 2024/11/10 11:45⇒頻度30分⇒2024/11/10 11:15
-
- 2024/11/10 11:15⇒ウィンドウサイズ1時間⇒2024/11/10 10:15
OK!計算通りです。
頻度変更後のスケジュールされた自動増分更新(3 回目)
▼ 2024/11/10 21:15 JST 実行クエリ
/* QuickSight a1e1d96b-668b-4da2-a904-ad78384e30ba */
SELECT "formatted_date", "department", "section", "status", "donut"
FROM (SELECT
date_parse(partition_date, '%Y/%m/%d/%H') AS formatted_date,
department,
section,
status,
donut
FROM
spiceincrementalupdatedb.sweets_with_status
GROUP BY
partition_date,
department,
section,
status,
donut
ORDER BY
formatted_date,
department,
section) AS "sweets_with_status_donut"
WHERE "formatted_date" > from_unixtime(cast(substr(cast(1731235523686 as varchar), 1, 10) AS bigint))
時間確認
select from_unixtime(cast(substr(cast(1731235523686 as varchar), 1, 10) AS bigint))
実行結果:2024-11-10 10:45:23.000
OK ですね。
E. 結果:SPICE 増分更新のスケジュールの頻度のみを変更する際は必ず未来日付を指定する必要があり、変更保存後もフル更新は走らない
結果をまとめると以下になります。
- E. SPICE 増分更新のスケジュールの頻度のみを変更する際は必ず未来日付を指定する必要があり、変更保存後もフル更新は走らない
- 指定した未来日付から設定した頻度でスケジュール実行される
- 頻度を変更した 1 回目の SPICE 増分更新は、前回の取り込み範囲の後から漏れなく取り込むよう範囲指定される
おわりに
SPICE 増分更新は奥が深くて大変でした。ある程度腹落ちするまで検証でき図示もできたと思いますが、やはり複雑かなと思いますので、不明点があればお問い合わせください。増分更新は重複が発生しないデータで利用した方が良いと思います。
検証にも時間がかかりまして、スクショやクエリの日付からいかに私がこのブログを書くのに時間がかかってしまったかおわかりいただけたかと思います。一旦書き終われてよかったです。
本記事への質問やご要望については画面下部のお問い合わせ「DevelopersIO について」からご連絡ください。記事に関してお問い合わせいただけます。
参考