2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Snowflake NotebooksでGEOGRAPHY/GEOMETRY型を使うときに注意すること

Posted at

Snowflake Notebooks

Snowflake NotebooksはSnowflakeのWeb UIであるSnowSight上で提供されている開発環境です。SQL、Python、Markdownを一つのノート上に混在して記述できるのが特徴です。
雰囲気的にはJupyter Notebookのようなサービスになっています。

Snowflake Notebooks

2024/8/4現在、Public Preview (PuPr)中です。

GEOGRAPHY/GEOMETRY型

GEOGRAPHY/GEOMETRY型はそれぞれSQLで地理空間情報を扱うためのデータ型です。
GEOGRAPHY型は地球を球体として扱ったもので、GEOMETRY型は平面として扱ったものです。

なんか変だぞ

他のセルで定義されたGEOGRAPHY/GEOMETRY型のデータに対して地理空間情報を処理するための地理空間関数(ST_で始まる関数)が使えないことに気付きました。
なんで…?

error

原因を調べてみる

それぞれデータ型を確認してみると、SELECTした直後と他のセルから参照したときで変化していることが分かります。
SELECTした直後はVARIANT[LOB]で、他のセルから参照したときはOBJECT[LOB]になっています。

typeof

どうやら他のセルから参照したときは半構造化データ、つまり単なるJSON Objectになっているようです。
そのため、キーでアクセスできるようになっています。

JSON Object

なお、GEOGRAPHY型は以下のような半構造化データに、

{
  "coordinates": [-122.35, 37.55],
  "type": "Point"
}

GEOMETRY型は以下のような半構造化データになっています。

{
  "coordinates": [-1.223500000000000e+02, 3.755000000000000e+01],
  "type": "Point"
}

これらはGeoJSONフォーマットそのままだと思われます。

どうすればいいのか

セルを跨ぐたびにTO_GEOGRAPHYあるいはTO_GEOMETRYで明示的に型変換することで回避可能です。
それぞれの関数に<variant_expression>を与えたのと同じ挙動をするようです。

success

根本的な原因はRESULT_SCANにあり?

Snowflake Squad1前田健太郎さんに教えていただいたのですが、Snowflake Notebooksのセル結果参照はRESULT_SCAN関数で実装されているとのことです。
「キャッシュを永続化するときに型情報が削除されることはありそう」とのことで、そんな感じはしますよね…ということで簡単に検証してみます。

SQL Worksheetで以下のようなコードを書いて実行してみます。

geo_result_scan.sql
-- とりあえずGEOGRAPHY型のデータを作ってみる
SELECT ST_GEOGRAPHYFROMWKT('POINT(-122.35 37.55)') AS POINT;
-- クエリIDを取得
SELECT LAST_QUERY_ID();
-- 以降、クエリIDが01b61af4-0001-9a90-0000-afcd0026418eだったとする
-- 参照できることを確認
SELECT POINT FROM TABLE(RESULT_SCAN('01b61af4-0001-9a90-0000-afcd0026418e'));
-- 型情報を確認
SELECT SYSTEM$TYPEOF(POINT) FROM TABLE(RESULT_SCAN('01b61af4-0001-9a90-0000-afcd0026418e'));
-- 地理空間関数が使えないことを確認
SELECT ST_CENTROID(POINT) FROM TABLE(RESULT_SCAN('01b61af4-0001-9a90-0000-afcd0026418e'));
-- TO_GEOGRAPHYで明示的に型変換すれば地理空間関数が使えることを確認
SELECT ST_CENTROID(TO_GEOGRAPHY(POINT)) FROM TABLE(RESULT_SCAN('01b61af4-0001-9a90-0000-afcd0026418e'));
-- TO_GEOGRAPHYで明示的に型変換した後の型情報を確認
SELECT SYSTEM$TYPEOF(TO_GEOGRAPHY(POINT)) FROM TABLE(RESULT_SCAN('01b61af4-0001-9a90-0000-afcd0026418e'));

同様の挙動を再現することができました。

worksheets

まとめ

Snowflake Notebooksのセル結果参照やRESULT_SCANは一見効率がよさそうに思えるのですが、RESULT_SCANの以下の記載の通り、大規模なデータを扱うときには性能的に不利になることもあります。

結果セットにはメタデータが関連付けられていないため、大きな結果の処理は、実際のテーブルをクエリする場合よりも遅くなる可能性があります。

Notebook系のサービスを使うときにデータ全体から使うデータを徐々に絞り込んでいきたいシーンがしばしばありますが、共通テーブル式(CTE)などでクエリそのものを修正していくことが有効なこともあるので、挙動を理解して柔軟に対応していきましょう!
もちろん、可読性が損なわれなければ都度TO_GEOGRAPHYあるいはTO_GEOMETRYを呼び出すのもありだと思います。

  1. Snowflake社から技術力や発信力を認められたSnowflakeアンバサダーのこと

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?