Snowflakeのアンロードで単一ファイルと複数ファイルを比較してみた #SnowflakeDB

2021.12.05

※本エントリは、Snowflakeをより使いこなそう! Advent Calendar 2021の5日目の記事となります。

さがらです。

Snowflakeではテーブル上のデータをアンロード出来るのですが、その際単一ファイルとして出力するのか、複数ファイルとして出力するのか、で仕様や挙動が異なります。

その違いについて、本エントリでまとめてみます。

データのアンロードとは

通常COPYコマンドはステージにあるファイルをテーブルにロードするときに使うと思いますが、実はCOPYコマンドを使って、テーブル上のデータをステージに出力することができます。これがアンロードです。

アンロード自体については、実はすでに詳細にまとめられた記事が投稿済です。

この私の記事では「単一ファイルと複数ファイルでの違い」にフォーカスしますが、アンロードの全体像を知りたい場合は是非こちらのブログをご覧ください。

比較してみる

「ファイルサイズ」「ファイル名」「アンロード時の所要時間」この3つの観点から比較してみます。

前提条件

  • ウェアハウス:サイズS、最大クラスター数1
  • アンロード先:ユーザーステージを使用します。
  • 対象テーブル:Snowflakeのサンプルデータとして提供されている、"SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF10TCL"."CUSTOMER"を使用します。(6500万行、2.9GBのデータです。)

  • 実行するコマンド(単一ファイルのとき)
copy into @~/users/customer.csv.gz from "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF10TCL"."CUSTOMER"
    file_format = (type = csv compression = 'gzip')
    max_file_size=4900000000 -- 約4.9GB
    single = true;
  • 実行するコマンド(複数ファイルのとき)
copy into @~/users/customer from "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF10TCL"."CUSTOMER"
    file_format = (type = csv compression = 'gzip');

ファイルサイズ

まず、これは検証するまでもなく公式Docに仕様が書いてあります!

MAX_FILE_SIZEというオプションがあるのですが、この最大値が「5GB」です。 そのため、以下のような違いとなります。

  • 単一ファイル:最大5GB
  • 複数ファイル:複数ファイルに分かれるので、基本的に無制限(無制限とは言っても、TB以上のデータはストレージも圧迫するので注意が必要です。)

アンロード時の所要時間

早速ですが、アンロード時にかかった時間はこちらになります。

  • 単一ファイル:5分29秒
  • 複数ファイル:34.65秒

ということで、かなり違いがありますね!

ファイル名

まず、大きな違いは下記になります。その後でより詳細な仕様についてまとめておきます。

  • COPYコマンドの後に指定したステージのパスのファイル名がそのまま出力される
  • COPYコマンドの後に指定したステージのパスのファイル名に、 x_y_zの形でサフィックスが付与される

単一ファイルの時

単一ファイルのときは、必ず拡張子も含めてファイル名を指定する必要があります。

この仕様は、公式DocFILE_EXTENSIONのオプションの説明文にも書いてあります。

SINGLE コピーオプションが TRUE の場合、 COPY コマンドはデフォルトでファイル拡張子のないファイルをアンロードします。ファイル拡張子を指定するには、 内部ロケーション または 外部ロケーション パスにファイル名と拡張子を指定します。例:copy into @stage/data.csv ...

  • 良い例:copy into @~/users/customer.csv.gz
  • NGな例:copy into @~/users/customer

複数ファイルの時

複数ファイルのときは、x_y_zの形でサフィックスが付与されるのですが、下記の仕様に基づいて付与されています。

  • x: サーバ番号
  • y: スレッド番号
  • z: シーケンシャル番号

実はこの情報、公式Docには載っておらず、下記のページに情報があります(私自身もSnowflake社の方に教えて頂きました)。

そしてこの仕様がどういった時に影響するかと言うと、1つのウェアハウスで複数のクエリを処理していたり、ウェアハウスのサイズを変更すると、全く同じコマンドでもサフィックスが異なってきます

以下、ウェアハウスのサイズを試してみます。

  • ウェアハウスのサイズが「S」の時

こちらは、0_y_zから1_y_zまでサーバ番号が付与されています。

  • ウェアハウスのサイズが「L」の時

こちらは、0_y_zから7_y_zまでサーバ番号が付与されています。(LはSの4倍のスペックを持っているからですかね?)

つまり、複数ファイル出力時のサフィックスは常に変わるものであるため、アンロード後のパイプラインではこのサフィックスに依存しない仕様にしましょう!

次回

Snowflakeをより使いこなそう! Advent Calendar 2021、次回の6日目では、「タイムトラベルの設定で上位オブジェクトで設定された値は下位オブジェクトにどう影響するか確かめてみた」というタイトルで執筆します。お楽しみに!