pg_clickhouse チュートリアル
概要
このチュートリアルでは、[ClickHouse tutorial] に従いながら、すべてのクエリを pg_clickhouse 経由で実行します。
ClickHouse を起動する
まず、まだ ClickHouse データベースがない場合は、新しく作成してください。手軽に始めるには、Docker イメージを利用する方法があります。
テーブルを作成する
[ClickHouse tutorial] を参考に、ニューヨーク市タクシーのデータセットを使ってシンプルなデータベースを作成します。
データセットを追加
次にデータをインポートします。
クエリを実行できることを確認したら、クライアントを終了してください。
pg_clickhouse をインストールする
PGXN または GitHub から pg_clickhouse をビルドしてインストールします。もしくは、[pg_clickhouse image] を使って Docker コンテナを起動します。このイメージは、Docker の Postgres image に pg_clickhouse を追加したものです。
pg_clickhouse に接続
次に、Postgres に接続して pg_clickhouse を作成します。
ClickHouse データベース用の外部サーバーを、ホスト名、ポート、データベースを指定して作成します。
ここでは ClickHouse のバイナリプロトコルを利用するバイナリドライバーを使用します。代わりに、HTTP インターフェースを利用する「http」ドライバーを使うこともできます。
次に、PostgreSQL のユーザーを ClickHouse のユーザーにマッピングします。最も簡単な方法は、 現在の PostgreSQL ユーザーを、その外部サーバー用のリモートユーザーにマッピングすることです。
password オプションを指定することもできます。
次に、taxi テーブルを追加します。リモートの ClickHouse データベースにあるすべてのテーブルを Postgres のスキーマにインポートするだけです。
これでテーブルのインポートが完了しているはずです。psql で \det+ を使用して確認してみましょう:
成功しました! すべてのカラムを表示するには \d を実行してください。
次に、テーブルに対してクエリを実行します:
クエリがどれだけ速く実行されたかに注目してください。pg_clickhouse は COUNT() 集約を含むクエリ全体をプッシュダウンするため、ClickHouse 上で実行され、Postgres には 1 行だけが返されます。EXPLAIN を使って確認してみましょう。
プランのルートに「Foreign Scan」が表示されていることに注目してください。これは、クエリ全体が ClickHouse にプッシュダウンされたことを意味します。
データを分析する
いくつかクエリを実行してデータを分析してみましょう。以下の例を試すか、 独自の SQL クエリを実行してください。
-
チップの平均額を計算する:
-
乗客数に基づいて平均費用を算出します:
-
地区ごとの日次ピックアップ数を計算します:
-
各乗車の所要時間を分単位で計算し、その値を乗車時間ごとにグループ化します:
-
各地区ごとの乗車回数を、時間帯ごとに表示します:
-
ラガーディア空港またはJFK空港行きの乗車データを取得する:
Dictionary を作成する
ClickHouse サービス内のテーブルに関連付けられた Dictionary を作成します。 テーブルと Dictionary は、ニューヨーク市の各地区ごとに 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 の dictionary であるtaxi_zone_dictionaryを作成し、 S3 上の CSV ファイルから Dictionary を取り込みます:注記LIFETIMEを 0 に設定すると、自動更新が無効になり、S3 バケットへの 不要なトラフィックを防ぐことができます。別のケースでは、異なる値を 設定することもあります。詳細については、Refreshing dictionary data using LIFETIME を参照してください。- 次にインポートします:
- クエリ可能であることを確認します:
- うまくいきました。次に
dictGet関数を使って、 クエリ内で borough 名を取得します。このクエリでは、 LaGuardia または JFK 空港で終了するタクシー乗車数を borough ごとに合計します:
このクエリは、LaGuardia または JFK 空港で終了するタクシー乗車数を borough ごとに合計します。pickup の地区が不明なトリップがかなり多いことが わかります。
JOIN を実行する
taxi_zone_dictionary を trips テーブルと結合するクエリをいくつか書きます。
-
まずは、上で示した空港に関するクエリと同様に動作する シンプルな
JOINから始めます:注記上記の
JOINクエリの出力は、(Unknownの値が含まれていない点を除けば) 先ほどのdictGetクエリと同じであることに注意してください。内部的には ClickHouse は、taxi_zone_dictionaryDictionary に対して実際にはdictGet関数を呼び出していますが、JOIN構文の方が SQL 開発者にはよりなじみがあります。 -
次のクエリは、チップ額が最も高い 1000 件の乗車について行を返し、 その後、各行を Dictionary と内部結合します:
一般的に、PostgreSQL と ClickHouse では SELECT * の使用は避けます。
実際に必要なカラムだけを取得するべきです。