クイックスタート
まずは簡単な例から始めましょう。ここでは ClickHouse に接続し、system データベースから SELECT を実行します。始めるには、接続情報が必要です。
接続情報
ClickHouse にネイティブ TCP で接続するには、次の情報が必要です。
| Parameters | 説明 |
|---|---|
HOST and PORT |
通常、TLS を使用する場合のポートは 9440、TLS を使用しない場合は 9000 です。 |
DATABASE NAME |
初期状態では default という名前のデータベースがあります。接続先のデータベース名を使用してください。 |
USERNAME and PASSWORD |
初期状態のユーザー名は default です。用途に応じたユーザー名を使用してください。 |
ClickHouse Cloud サービスの接続情報は、ClickHouse Cloud コンソールで確認できます。 接続先のサービスを選択し、Connect をクリックします。

Native を選択すると、接続情報が clickhouse-client コマンドの例として表示されます。

セルフマネージド ClickHouse を使用している場合、接続情報は ClickHouse 管理者が設定します。
モジュールを初期化
mkdir clickhouse-golang-example
cd clickhouse-golang-example
go mod init clickhouse-golang-exampleサンプルコードをコピーする
このコードを clickhouse-golang-example ディレクトリに main.go としてコピーします。
package main
import (
"context"
"crypto/tls"
"fmt"
"log"
"github.com/ClickHouse/clickhouse-go/v2"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
)
func main() {
conn, err := connect()
if err != nil {
panic(err)
}
ctx := context.Background()
rows, err := conn.Query(ctx, "SELECT name, toString(uuid) as uuid_str FROM system.tables LIMIT 5")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name, uuid string
if err := rows.Scan(&name, &uuid); err != nil {
log.Fatal(err)
}
log.Printf("name: %s, uuid: %s", name, uuid)
}
// 注意: rows.Err() のチェックを省略しないこと
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}
func connect() (driver.Conn, error) {
var (
ctx = context.Background()
conn, err = clickhouse.Open(&clickhouse.Options{
Addr: []string{"<CLICKHOUSE_SECURE_NATIVE_HOSTNAME>:9440"},
Auth: clickhouse.Auth{
Database: "default",
Username: "default",
Password: "<DEFAULT_USER_PASSWORD>",
},
ClientInfo: clickhouse.ClientInfo{
Products: []struct {
Name string
Version string
}{
{Name: "an-example-go-client", Version: "0.1"},
},
},
Debugf: func(format string, v ...interface{}) {
fmt.Printf(format, v)
},
TLS: &tls.Config{
InsecureSkipVerify: true,
},
})
)
if err != nil {
return nil, err
}
if err := conn.Ping(ctx); err != nil {
if exception, ok := err.(*clickhouse.Exception); ok {
fmt.Printf("Exception [%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
}
return nil, err
}
return conn, nil
}go mod tidy を実行
go mod tidy接続情報を設定する
先ほど確認した接続情報を、main.go の connect() 関数に設定します。
func connect() (driver.Conn, error) {
var (
ctx = context.Background()
conn, err = clickhouse.Open(&clickhouse.Options{
Addr: []string{"<CLICKHOUSE_SECURE_NATIVE_HOSTNAME>:9440"},
Auth: clickhouse.Auth{
Database: "default",
Username: "default",
Password: "<DEFAULT_USER_PASSWORD>",
},例を実行する
go run .2023/03/06 14:18:33 name: COLUMNS, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: SCHEMATA, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: TABLES, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: VIEWS, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: hourly_data, uuid: a4e36bd4-1e82-45b3-be77-74a0fe65c52bさらに詳しく
このカテゴリの以降のドキュメントでは、ClickHouse Go client の詳細を説明します。
概要
ClickHouse は 2 つの公式 Go クライアントをサポートしています。これらのクライアントは相互補完的であり、それぞれ異なるユースケースに対応するよう意図的に設計されています。
- clickhouse-go - Go 標準の
database/sqlインターフェイス、またはネイティブ ClickHouse API のいずれかをサポートする高水準クライアント。 - ch-go - 低水準クライアント。ネイティブインターフェイスのみをサポートします。
clickhouse-go は高水準のインターフェイスを提供し、ユーザーは行指向のセマンティクスとバッチ処理を使用してデータのクエリや挿入を行えます。データ型に対する許容度が高く、精度の損失が生じる可能性がない限り、値は変換されます。一方、ch-go は最適化されたカラム指向のインターフェイスを提供し、型の厳密さやより複雑な利用方法が求められる代わりに、CPU とメモリのオーバーヘッドを低く抑えた高速なデータブロックのストリーミングを実現します。
バージョン 2.3 以降、clickhouse-go はエンコード、デコード、圧縮などの低水準機能に ch-go を利用しています。両クライアントは最適なパフォーマンスを実現するためにエンコードに Native format を使用しており、ネイティブ ClickHouse プロトコルで通信できます。clickhouse-go は、ユーザーがトラフィックをプロキシまたはロードバランスする必要がある場合に備えて、転送メカニズムとして HTTP もサポートしています。
接続方法は4通り
clickhouse-go では、どの API を使うかと どの転送方式 を使うかという、独立した 2 つの選択肢があります。これらの組み合わせで、接続モードは 4 通りになります。
| TCP (ネイティブプロトコル、ポート 9000/9440) | HTTP (ポート 8123/8443) | |
|---|---|---|
ClickHouse API (clickhouse.Open) |
デフォルト — 最高のパフォーマンス | Protocol: clickhouse.HTTP を設定 |
database/sql API (OpenDB / sql.Open) |
clickhouse://host:9000 |
http://host:8123 |
API の選択: 最高のパフォーマンスとフル機能セット (進捗コールバック、列指向 insert、豊富な型サポート) が必要なら、ClickHouse API を選んでください。ORM や標準的な Go のデータベースインターフェイスを前提とするツールと連携する必要がある場合は、database/sql を選んでください。
転送方式の選択: TCP のほうが高速で、デフォルトでもあります。インフラストラクチャ上の要件で必要な場合は HTTP に切り替えてください。たとえば、HTTP ロードバランサーやプロキシ経由で接続する場合や、一時テーブルを使ったセッション、追加の圧縮アルゴリズム (gzip, deflate, br) など、HTTP 固有の機能が必要な場合です。
どちらの API でも、転送方式にかかわらずネイティブのバイナリ encoding を使用するため、HTTP でもシリアライゼーションのオーバーヘッドはありません。
| ネイティブフォーマット | TCP transport | HTTP transport | Bulk write | Struct marshaling | Compression | Progress callbacks | |
|---|---|---|---|---|---|---|---|
| ClickHouse API | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
database/sql API |
✅ | ✅ | ✅ | ✅ | ✅ |
クライアントの選択
クライアントライブラリの選定は、利用パターンと求めるパフォーマンスによって異なります。1 秒あたり数百万件の insert が必要な、insert 負荷の高いユースケースでは、低レベルクライアントの ch-go の使用を推奨します。このクライアントは、ClickHouse の Native format で必要となる、行指向フォーマットからカラムへのデータ変換に伴うオーバーヘッドを回避します。さらに、使いやすさを保つために、リフレクションや interface{} (any) 型も使用しません。
集計中心のクエリワークロードや、スループットがそれほど高くない insert ワークロードでは、clickhouse-go は使い慣れた database/sql インターフェイスと、より分かりやすい行ベースの扱いを提供します。さらに、転送プロトコルとして HTTP を任意で使用でき、ヘルパー関数を使って行と構造体を相互にマーシャリングできます。
| ネイティブフォーマット | ネイティブプロトコル | HTTPプロトコル | 行指向 API | カラム指向 API | 型の柔軟性 | 圧縮 | クエリプレースホルダー | |
|---|---|---|---|---|---|---|---|---|
| clickhouse-go | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| ch-go | ✅ | ✅ | ✅ | ✅ |
インストール
ドライバーの v1 は非推奨であり、今後、機能更新や新しい ClickHouse 型のサポートは行われません。より高いパフォーマンスを備えた v2 への移行を推奨します。
クライアントの 2.x バージョンをインストールするには、go.mod ファイルにパッケージを追加します。
require github.com/ClickHouse/clickhouse-go/v2 main
または、リポジトリをクローンします。
git clone --branch v2 https://github.com/clickhouse/clickhouse-go.git $GOPATH/src/github別のバージョンをインストールするには、必要に応じてパスまたはブランチ名を変更します。
mkdir my-clickhouse-app && cd my-clickhouse-app
cat > go.mod <<-END
module my-clickhouse-app
go 1.21
require github.com/ClickHouse/clickhouse-go/v2 main
END
cat > main.go <<-END
package main
import (
"fmt"
"github.com/ClickHouse/clickhouse-go/v2"
)
func main() {
conn, _ := clickhouse.Open(&clickhouse.Options{Addr: []string{"127.0.0.1:9000"}})
v, _ := conn.ServerVersion()
fmt.Println(v.String())
}
END
go mod tidy
go run main.goバージョニング
このクライアントは、ClickHouseとは独立してリリースされています。2.x は現在開発中のメジャーバージョンです。2.x のすべてのバージョンは相互に互換性がある想定です。
ClickHouse 互換性
このクライアントは、以下をサポートしています。
- こちらに記載されている、現在サポート対象の ClickHouse のすべてのバージョン。ClickHouse の各バージョンはサポート対象外になると、そのクライアントリリースに対するアクティブなテストも行われなくなります。
- クライアントのリリース日からさかのぼって 2 年以内にリリースされた、すべてのバージョンの ClickHouse。なお、アクティブにテストされるのは LTS バージョンのみです。
Golangの互換性
| クライアントのバージョン | Golangのバージョン |
|---|---|
| => 2.0 <= 2.2 | 1.17, 1.18 |
| >= 2.3, < 2.41 | 1.18+ |
| >= 2.41 | 1.21+ |
| >= 2.43 | 1.24+ |
ベストプラクティス
- 可能であれば、特にプリミティブ型では ClickHouse API を利用してください。これにより、大量のリフレクションや間接処理を避けられます。
- 大規模なデータセットを読み取る場合は、
BlockBufferSizeの変更を検討してください。これによりメモリ使用量は増えますが、行の反復処理中により多くのブロックを並列にデコードできるようになります。デフォルト値の 2 は控えめな設定で、メモリオーバーヘッドを最小限に抑えます。値を大きくすると、メモリ上に保持されるブロックも増えます。クエリによってブロックサイズは異なるため、テストが必要です。そのため、Context を介して クエリレベル で設定できます。 - データを挿入する際は、型を明確に指定してください。クライアントは柔軟性を重視しており、たとえば UUID や IP に対して文字列を parse できるようになっていますが、そのためにはデータの検証が必要になり、挿入時のコストが発生します。
- 可能であれば、カラム指向の挿入を使用してください。これらについても厳密に型を指定し、クライアント側で値を変換する必要がないようにしてください。
- 最適な挿入パフォーマンスを得るために、ClickHouse の推奨事項に従ってください。
次のステップ
- 設定 — 接続設定、TLS、認証、ログ、圧縮
- ClickHouse API — クエリ実行とデータ挿入のためのネイティブなGo API
- Database/SQL API — 標準の
database/sqlインターフェイス - データ型 — Goの型マッピングと複合型のサポート