[新機能]Snowflakeでパフォーマンスが向上した新しいウェアハウス「Generation 2 standard warehouses」がリリースされたので、従来のウェアハウスと速度比較してみた
さがらです。
Snowflakeでパフォーマンスが向上した新しいウェアハウス「Generation 2 standard warehouses」がリリースされました。
この新しいウェアハウスを使って従来のウェアハウスと速度比較してみたので、その内容をまとめてみます。
Generation 2 standard warehouseとは
以下、公式ドキュメントからの引用の日本語訳ですが、従来の仮想ウェアハウスの次世代版で、よりパフォーマンス向上がしたウェアハウスが「Generation 2 standard warehouses」となります。
第2世代標準ウェアハウス(Gen2)は、Snowflakeの現在の標準仮想ウェアハウスの更新版(「次世代」)であり、分析およびデータエンジニアリングワークロードのパフォーマンス向上に重点を置いています。Gen2は、高速化された基盤ハードウェアと、削除、更新、マージ操作、テーブルスキャン操作の強化など、インテリジェントなソフトウェア最適化を基盤として構築されています。Gen2を使用すると、ほとんどのクエリがより速く完了し、同時により多くの処理を実行できるようになります。
使用できるリージョン
本機能はリリース時からGAでの提供ですが、以下のリージョンのみ利用可能となっています。
- AWS us-west-2 (Oregon)
- AWS eu-central-1 (Frankfurt)
- Azure East US 2 (Virginia)
- Azure West Europe (Netherlands)
コスト
Snowflake Service Consumption Tableを見ると、下図のようなコストとなっております。通常のウェアハウスと比較して、AWSの場合は1.35倍、Azureの場合は1.25倍というコストになります。
試してみた
実際に、これまでのウェアハウスと比較してクエリの速度がどう変更されるかを確かめてみます。
ウェアハウスの定義
以下のクエリを実行して、検証用のウェアハウスを定義します。「Generation 2 standard warehouses」のウェアハウスを使う場合は、resource_constraint = standard_gen_2
とすればOKです。
-- 比較用の従来のウェアハウス定義
create or replace warehouse large_wh_gen1
warehouse_size = large;
-- Gen2のウェアハウス定義
create or replace warehouse large_wh_gen2
resource_constraint = standard_gen_2
warehouse_size = large;
検証用のクエリ
Snowflakeのサンプルデータとして提供されているTPC-DS用のサンプルクエリを用いて、検証していきます。データ量として、snowflake_sample_data.tpcds_sf10tcl.store_returns
テーブルは29億行のテーブル、snowflake_sample_data.tpcds_sf10tcl.web_sales
テーブルは72億行のテーブルです。
それぞれのクエリの実行前に、クエリキャッシュを無効化してウェアハウスも一度停止して、キャッシュが効かないようにします。
- 従来のウェアハウス検証前 準備クエリ
-- セッションレベルでクエリキャッシュを無効化
alter session set use_cached_result = false;
-- 従来のウェハウスを一度停止して、再度有効化
alter warehouse large_wh_gen1 suspend;
alter warehouse large_wh_gen1 resume;
use warehouse large_wh_gen1;
-- クエリ対象のスキーマを決定
use schema snowflake_sample_data.tpcds_sf10tcl;
- Gen2ウェアハウス検証前 準備クエリ
-- セッションレベルでクエリキャッシュを無効化
alter session set use_cached_result = false;
-- Gen2のウェハウスを一度停止して、再度有効化
alter warehouse large_wh_gen2 suspend;
alter warehouse large_wh_gen2 resume;
use warehouse large_wh_gen2;
-- クエリ対象のスキーマを決定
use schema snowflake_sample_data.tpcds_sf10tcl;
- クエリ1
with customer_total_return as
(select sr_customer_sk as ctr_customer_sk
,sr_store_sk as ctr_store_sk
,sum(SR_RETURN_AMT_INC_TAX) as ctr_total_return
from store_returns
,date_dim
where sr_returned_date_sk = d_date_sk
and d_year =1999
group by sr_customer_sk
,sr_store_sk)
select c_customer_id
from customer_total_return ctr1
,store
,customer
where ctr1.ctr_total_return > (select avg(ctr_total_return)*1.2
from customer_total_return ctr2
where ctr1.ctr_store_sk = ctr2.ctr_store_sk)
and s_store_sk = ctr1.ctr_store_sk
and s_state = 'NM'
and ctr1.ctr_customer_sk = c_customer_sk
order by c_customer_id
limit 100;
- クエリ2
with wscs as
(select sold_date_sk
,sales_price
from (select ws_sold_date_sk sold_date_sk
,ws_ext_sales_price sales_price
from web_sales
union all
select cs_sold_date_sk sold_date_sk
,cs_ext_sales_price sales_price
from catalog_sales) x ),
wswscs as
(select d_week_seq,
sum(case when (d_day_name='Sunday') then sales_price else null end) sun_sales,
sum(case when (d_day_name='Monday') then sales_price else null end) mon_sales,
sum(case when (d_day_name='Tuesday') then sales_price else null end) tue_sales,
sum(case when (d_day_name='Wednesday') then sales_price else null end) wed_sales,
sum(case when (d_day_name='Thursday') then sales_price else null end) thu_sales,
sum(case when (d_day_name='Friday') then sales_price else null end) fri_sales,
sum(case when (d_day_name='Saturday') then sales_price else null end) sat_sales
from wscs
,date_dim
where d_date_sk = sold_date_sk
group by d_week_seq)
select d_week_seq1
,round(sun_sales1/sun_sales2,2)
,round(mon_sales1/mon_sales2,2)
,round(tue_sales1/tue_sales2,2)
,round(wed_sales1/wed_sales2,2)
,round(thu_sales1/thu_sales2,2)
,round(fri_sales1/fri_sales2,2)
,round(sat_sales1/sat_sales2,2)
from
(select wswscs.d_week_seq d_week_seq1
,sun_sales sun_sales1
,mon_sales mon_sales1
,tue_sales tue_sales1
,wed_sales wed_sales1
,thu_sales thu_sales1
,fri_sales fri_sales1
,sat_sales sat_sales1
from wswscs,date_dim
where date_dim.d_week_seq = wswscs.d_week_seq and
d_year = 1999) y,
(select wswscs.d_week_seq d_week_seq2
,sun_sales sun_sales2
,mon_sales mon_sales2
,tue_sales tue_sales2
,wed_sales wed_sales2
,thu_sales thu_sales2
,fri_sales fri_sales2
,sat_sales sat_sales2
from wswscs
,date_dim
where date_dim.d_week_seq = wswscs.d_week_seq and
d_year = 1999+1) z
where d_week_seq1=d_week_seq2-53
order by d_week_seq1;
検証結果
クエリ1
平均して、2.6秒ほどGen2のウェアハウスの方が速い結果となりました。
ウェアハウスの種類 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 平均 |
---|---|---|---|---|---|---|
従来 | 8.7s | 9.4s | 8.9s | 10s | 8.7s | 9.14s |
Gen2 | 7.4s | 6.2s | 6.1s | 6.4s | 6.7s | 6.56s |
クエリプロファイルも載せておきます。Gen2のウェアハウスの方がAggregateの処理にかかった比率が少ないことがわかります。
- 従来のウェアハウス
- Gen2のウェアハウス
クエリ2
平均して、24秒ほどGen2のウェアハウスの方が速い結果となりました。クエリ1とここまで差が出たことに驚きましたね…!
ウェアハウスの種類 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 平均 |
---|---|---|---|---|---|---|
従来 | 48s | 48s | 47s | 48s | 49s | 48.00s |
Gen2 | 17s | 14s | 13s | 12s | 12s | 13.60s |
クエリプロファイルも載せておきます。Gen2のウェアハウスの方がAggregateやJoinの処理にかかった比率が少ないことがわかります。クエリ1のスキャン量が「4.09GB」、クエリ2のスキャン量が「66.83GB」のため、スキャン量が多いほどGen2のウェアハウスの性能が活きてきそうですね。
- 従来のウェアハウス
- Gen2のウェアハウス
最後に
Snowflakeでパフォーマンスが向上した新しいウェアハウス「Generation 2 standard warehouses」がリリースされましたので、実際に従来のウェアハウスと比較して速度比較をしてみました。
特にクエリ2の差には驚きましたね…処理時間が倍以上違うので、ウェアハウスの単価が1.35倍になることを考慮しても、Gen2のウェアハウスの方がコスト効率が明らかに良いことがわかります。
今回は2つのクエリでしか試していませんが、この検証範囲においてはスキャン量が多く、Aggregateなどの処理が多いクエリの場合に特に性能が発揮できるのでは、と感じました。
現在は日本のリージョンではまだ利用できませんが、リリースが待ち遠しくなる検証結果でしたね。日本のリージョンでもリリースされた場合にはぜひお試しください!