pg_clickhouse チュートリアル
概要
本チュートリアルは [ClickHouse tutorial] の流れに従いますが、すべてのクエリを pg_clickhouse 経由で実行します。
ClickHouse を起動する
まず、まだ ClickHouse データベースを持っていない場合は作成してください。手早く開始する方法としては、Docker イメージを利用するのが簡単です。
テーブルを作成する
[ClickHouse チュートリアル] を参考にして、ニューヨーク市のタクシーデータセットを用いた簡単なデータベースを作成します。
データセットを追加する
次に、データをインポートします:
クエリを実行できることを確認したら、クライアントを終了します。
pg_clickhouse をインストールする
PGXN または GitHub から pg_clickhouse をビルドしてインストールします。あるいは、[pg_clickhouse image] を使用して Docker コンテナを起動します。このイメージは、pg_clickhouse を Docker の Postgres image に単に追加したものです。
pg_clickhouse に接続する
次に、Postgres に接続します。
次に、pg_clickhouse を作成します:
ClickHouse データベースに対して、ホスト名、ポート、およびデータベース名を指定して外部サーバーを作成します。
ここでは、ClickHouse バイナリプロトコルを使用するバイナリドライバを選択しています。HTTP インターフェイスを使用する「http」ドライバを使うこともできます。
次に、PostgreSQL ユーザーを ClickHouse の USER にマッピングします。最も簡単な方法は、現在の PostgreSQL ユーザーを、その外部サーバー上のリモート USER にマッピングすることです。
password オプションを指定することもできます。
次に、taxi テーブルを追加します。リモートの ClickHouse データベースにあるすべてのテーブルを Postgres のスキーマにインポートするだけで済みます。
これでテーブルがインポートされたはずです。psql で \det+ を実行して確認してください:
成功しました! \d を使用してすべてのカラムを表示しましょう。
次に、テーブルにクエリを実行します:
クエリがどれほど高速に実行されたかに注目してください。pg_clickhouse は COUNT() 集約を含むクエリ全体をプッシュダウンするため、ClickHouse 上で実行され、Postgres 側には単一の行だけが返されます。EXPLAIN を使って確認しましょう。
プランのルートに「Foreign Scan」が現れている点に注目してください。これは、クエリ全体が ClickHouse にプッシュダウンされていることを意味します。
データを分析する
いくつかのクエリを実行してデータを分析します。以下の例を試すか、自分で SQL クエリを実行してみてください。
-
平均チップ額を計算する:
-
乗客数に基づく平均コストを計算します:
-
各地区ごとの1日あたりのピックアップ件数を計算します:
-
各乗車の所要時間を分単位で計算し、その結果を所要時間ごとにグループ化します:
-
各地区別の乗車数を、1日の各時間ごとに表示します:
-
LaGuardia 空港または JFK 空港への乗車データを取得します:
Dictionary を作成する
ClickHouse サービス内のテーブルに関連付けられた Dictionary を作成します。 テーブルと Dictionary は、ニューヨーク市の各地区(neighborhood)ごとに 1 行を持つ CSV ファイルに基づいています。
これらの地区は、ニューヨーク市の 5 つの行政区(Bronx, Brooklyn, Manhattan, Queens, Staten Island)および Newark Airport (EWR) にマッピングされています。
以下は、使用している CSV ファイルの一部をテーブル形式で示したものです。
ファイル内の LocationID カラムは、trips テーブル内の pickup_nyct2010_gid カラムおよび dropoff_nyct2010_gid カラムと対応しています:
| LocationID | Borough | Zone | service_zone |
|---|---|---|---|
| 1 | EWR | Newark Airport | EWR |
| 2 | Queens | Jamaica Bay | Boro Zone |
| 3 | Bronx | Allerton/Pelham Gardens | Boro Zone |
| 4 | Manhattan | Alphabet City | Yellow Zone |
| 5 | Staten Island | Arden Heights | Boro Zone |
-
引き続き Postgres 上で、
clickhouse_raw_query関数を使用して ClickHouse の dictionarytaxi_zone_dictionaryを作成し、 S3 上の CSV ファイルから Dictionary を読み込みます:注記LIFETIMEを 0 に設定すると、自動更新が無効になり、S3 バケットへの 不要なトラフィックを避けることができます。別のケースでは、異なる値を 設定することもあります。詳細については、Refreshing dictionary data using LIFETIME を参照してください。- 次に、これをインポートします:
- クエリできることを確認します:
- 問題なく動作していることが確認できました。次に
dictGet関数を使用して、 クエリ内で borough の名前を取得します。このクエリでは、 LaGuardia か JFK のいずれかの空港で終了するタクシー乗車数を、 borough ごとに集計します:
このクエリは、LaGuardia か JFK のいずれかの空港で終了するタクシー乗車数を、 borough ごとに集計します。pickup 側の地区が不明な乗車がかなり多いことに 注目してください。
結合を実行する
taxi_zone_dictionary と trips テーブルを結合するクエリをいくつか作成します。
-
まずは、上の空港に関するクエリと同様に動作する、シンプルな
JOINから始めます:注記上記の
JOINクエリの出力は、(「Unknown」値が含まれていない点を除き)上で示したdictGetクエリと同じであることに注意してください。内部的には、ClickHouse は実際にはtaxi_zone_dictionaryDictionary に対してdictGet関数を呼び出していますが、JOIN構文の方が SQL 開発者にはより馴染みがあります。 -
このクエリは、チップ額が最も高い 1000 件のトリップについて行を返し、その後、 各行ごとに Dictionary と内部結合を行います:
一般的に、PostgreSQL と ClickHouse では SELECT * の使用は避けます。
実際に必要なカラムだけを取得すべきです。