🗺️

DuckDB v1.5 の GIS エンジニア的に注目のアップデート

に公開

DuckDB v1.5 は、来年2月にリリース予定です。ということで、まだちょっと気が早いんですが、そこで入る予定の変更を3つ紹介します。

GEOMETRY型が DuckDB 本体に入る

ついに! Parquet に GEOMETRY 型ができたわけなので、DuckDB に入るのも時間の問題でしたが(v1.4の前から話は出ていた)、v1.5 でついに正式に DuckDB のネイティブの型になります。

DuckDB 本体:
https://github.com/duckdb/duckdb/pull/19136

DuckDB spatial:
https://github.com/duckdb/duckdb-spatial/pull/713

で、これで何が変わるの?というところですが、実はユーザーが意識するところはあまりありません。GEOMETRY 型のデータを読み書きするのが DuckDB 本体でできるようになっても、実際にその GIS データを操作する ST_* 関数は spatial 拡張にあるので LOAD spatial はあなたのコードから消えないでしょう。

ただ、内部実装的には、本体入りしたことでいろいろな最適化の余地が増えました。私も全貌は理解できてないんですが、pull request に書かれていた話を2つ紹介します。

geometry statistics がサポートされた

https://github.com/duckdb/duckdb/pull/19203
https://github.com/duckdb/duckdb/pull/19439

と言われても何のことやら、という感じだと思いますが、要は bbox でのデータの絞り込みがより効率的にできるようになりました。

Parquet/GeoParquet にはさまざまなレベルで bbox 情報が記録されています。DuckDB v1.5 では、row group 単位で bbox による絞り込みが自動(v1.4 でも手動ではできる)で行われるようになりました。「row group 単位」というのが何なのかピンとこない方は、以下の記事で軽く説明を書いたので読んでみてください。これで SedonaDB に追いついたかたちですね。

https://zenn.dev/mierune/articles/87f7c88d213376#違い1%3A-bbox

データの読み書きの効率化

DuckDB spatial(上に貼ったのと同じ):
https://github.com/duckdb/duckdb-spatial/pull/713

GDAL との連携が強化されて、データの読み書きがより効率的になりました。

まず、COPY (...) TO ... (FORMAT GDAL)は、Apache Arrow 形式で GDAL にデータを渡すようになりました。これによって、データの書き出しが大幅に高速化した、とのことです。

また、データを読む方も、ST_Read で bbox での pushdown が自動で行われるようになりました。今は spatial_filterspatial_filter_box というオプションで手動で調整できるみたいですが、自動でいい感じになるのでこのオプションも消えるみたいです。

あと、マニアックな変更としては、これまでも register_geoarrow_extensions() という知る人ぞ知る関数を呼び出すと出力が GeoArrow 形式になってたんですが、v1.5 ではデフォルトで GeoArrow になりました。これは DuckDB WASM でデータを吐き出して deck.gl に渡す時とかに便利なやつです。

(参考)まだ実装されていないもの

上に貼った pull request で、チェックボックスはあるけど多分まだ実装されていない?ものもいちおう見ておきましょう。

Dedicated geometry storage/compression

本体に統合されたことで、ジオメトリ型を内部的にどのようなフォーマットで扱うかという点にも自由度が持てるようになりました。現状、ジオメトリ型を表すバイナリ型と言えばWKB一択になってしまっていますが、Maxxenさんはバイク川崎バイクが好きすぎてWKBよりもっといいフォーマットあるんじゃないの??という提案を書いていたりして、期待が高まるところです。

https://github.com/Maxxen/Better-Known-Binary

Type-level CRS tracking/management

DuckDB spatial の重大なペインポイントとして、データに CRS を持たせられない、ということがあります。どういうことかというと、

ST_Transform(geometry, src, dst)

みたいに関数の引数に明示的に CRS を指定することはできるんですけど、

ST_Transform(geometry, dst)

のように変換元の CRS を省略することはできません。DuckDB はそのデータの CRS を知らないからです。

一方、SedonaDB ではこれができます。どうやっているかというと、カラムの型に CRS を埋め込んでるんですが、どうやら DuckDB も同じことをやろうとしてるみたいです。DuckDB の型のシステム上可能なのか?というあたりは私にはまったくわからないんですが、実現すれば SedonaDB に追いつくことになりますね。

Maybe GEOGRAPHY/"vectorized types" too

今回対応したのは GEOMETRY 型でしたが、GEOGRAPHY 型も対応するか?というあたりの話みたいです。GEOGRAPHY 型は、duckdb-geography という別のコミュニティ拡張にあって、いちおう統合したいねという話はこっちにも出ていました。

https://github.com/paleolimbot/duckdb-geography/issues/20

まとめ

備えよう。

MIERUNEのZennブログ

Discussion