OSSのデータウェアハウス比較:ClickHouse vs DuckDB vs Apache Druid でOLAP分析を高速化する
オープンソースラボ編集部 ・ 2026年6月14日
OSSのデータウェアハウス比較:ClickHouse vs DuckDB vs Apache Druid でOLAP分析を高速化する
Snowflake(月$25/クレジット〜)・BigQuery(従量課金・月数万〜)・Redshift(月$180〜)に対して、ClickHouse(最も高速なOSSカラムナOLAP・秒間数十億行)・DuckDB(インプロセスOLAP・Parquet直接クエリ)・Apache Druid(リアルタイムOLAP・大規模ダッシュボード)はOSSのデータウェアハウス・分析エンジンです。
OLAPデータウェアハウスが必要な場面
- 大規模ログ分析: 1日100億件のアクセスログをSQLで数秒クエリ
- リアルタイムダッシュボード: Kafka→ClickHouseで最新データを秒単位で可視化
- コスト削減: BigQueryの月数十万円をClickHouseセルフホストで$20/月に削減
- Pandas代替: 10GBのParquetファイルをDuckDBで200ms以下でクエリ
- マルチテナント分析: SaaS各テナントのデータを独立したパーティションで管理
主要ツールの概要
ClickHouse
2016年にYandexが公開したC++製のOSSカラムナデータベースです。GitHubスター38k+。単一ノードで毎秒数十億行を処理できる最速クラスのOLAPエンジンで、アクセスログ・イベントデータ・メトリクス・時系列データの分析に特化しています。PostHog・Sentry・CloudflareはClickHouseで大規模データを処理しています。
# ClickHouseをDockerで起動
docker run -d --name clickhouse -p 8123:8123 -p 9000:9000 -v clickhouse_data:/var/lib/clickhouse -e CLICKHOUSE_DB=analytics -e CLICKHOUSE_USER=default -e CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 -e CLICKHOUSE_PASSWORD=your-password clickhouse/clickhouse-server:latest
# ClickHouse Clientで接続
docker exec -it clickhouse clickhouse-client --password your-password
-- ClickHouseでWebアクセスログテーブルを作成
CREATE TABLE IF NOT EXISTS access_logs
(
timestamp DateTime,
user_id UInt64,
session_id String,
url String,
status_code UInt16,
response_ms UInt32,
country LowCardinality(String),
device LowCardinality(String)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, user_id)
TTL timestamp + INTERVAL 90 DAY; -- 90日後に自動削除
-- 高速集計クエリ(10億行でも数秒)
SELECT
toDate(timestamp) AS date,
country,
count() AS requests,
countIf(status_code >= 500) AS errors,
avg(response_ms) AS avg_latency_ms,
quantile(0.95)(response_ms) AS p95_latency_ms,
uniqExact(user_id) AS unique_users
FROM access_logs
WHERE timestamp >= now() - INTERVAL 30 DAY
GROUP BY date, country
ORDER BY date DESC, requests DESC
LIMIT 100;
-- MATERIALIZED VIEWで集計を事前計算(ダッシュボード高速化)
CREATE MATERIALIZED VIEW daily_stats
ENGINE = SummingMergeTree()
ORDER BY (date, country)
AS SELECT
toDate(timestamp) AS date,
country,
count() AS total_requests,
countIf(status_code >= 500) AS error_count,
sum(response_ms) AS total_latency
FROM access_logs
GROUP BY date, country;
# Python + clickhouse-driver でClickHouseを操作
pip install clickhouse-driver clickhouse-connect
from clickhouse_driver import Client
import pandas as pd
client = Client(
host="localhost",
port=9000,
database="analytics",
user="default",
password="your-password",
)
# バルクインサート(高速・100万行を数秒)
def insert_events(events: list[dict]):
client.execute(
"INSERT INTO access_logs (timestamp, user_id, url, status_code, response_ms, country, device) VALUES",
events,
types_check=True,
)
# クエリ結果をPandas DataFrameで取得
df = client.query_dataframe('''
SELECT
toStartOfHour(timestamp) AS hour,
url,
count() AS hits,
avg(response_ms) AS avg_ms
FROM access_logs
WHERE timestamp >= today() - 7
GROUP BY hour, url
HAVING hits > 1000
ORDER BY hour, hits DESC
''')
print(df.head(20))
# clickhouse-connect(HTTP API経由・より簡単)
import clickhouse_connect
http_client = clickhouse_connect.get_client(
host="localhost",
port=8123,
username="default",
password="your-password",
database="analytics",
)
result = http_client.query("SELECT count() FROM access_logs")
print(f"Total rows: {result.first_row[0]:,}")
// Next.js API RouteからClickHouseに接続してダッシュボードAPIを実装
// npm install @clickhouse/client
import { createClient } from "@clickhouse/client";
const clickhouse = createClient({
host: process.env.CLICKHOUSE_HOST!,
username: process.env.CLICKHOUSE_USER!,
password: process.env.CLICKHOUSE_PASSWORD!,
database: process.env.CLICKHOUSE_DATABASE!,
});
// app/api/analytics/route.ts
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const days = parseInt(searchParams.get("days") || "7");
const result = await clickhouse.query({
query: `
SELECT
toDate(timestamp) AS date,
count() AS page_views,
uniqExact(user_id) AS unique_visitors,
avg(response_ms) AS avg_response_ms
FROM access_logs
WHERE timestamp >= now() - INTERVAL {days:UInt8} DAY
GROUP BY date
ORDER BY date
`,
query_params: { days },
format: "JSONEachRow",
});
const data = await result.json();
return Response.json(data);
}
DuckDB
2019年に公開されたC++製のOSSインプロセス分析データベースです。GitHubスター26k+。インストール不要でParquet・CSV・JSONファイルを直接SQLクエリできるのが最大の特徴です。「分析用SQLite」とも呼ばれ、Pythonプロセス内に埋め込んで使えます。10GBのParquetファイルを数百ミリ秒でクエリできるため、Pandasのメモリ問題を解決する手段として急速に普及しています。
# DuckDB - pip install duckdb
import duckdb
# データベース不要: ParquetファイルをSQLで直接クエリ
conn = duckdb.connect()
# S3のParquetファイルを直接クエリ(S3 credentialが必要)
result = conn.execute('''
INSTALL httpfs;
LOAD httpfs;
SET s3_region='ap-northeast-1';
SET s3_access_key_id='...';
SET s3_secret_access_key='...';
SELECT
category,
count() AS count,
avg(price) AS avg_price,
sum(revenue) AS total_revenue
FROM read_parquet('s3://my-data-lake/sales/2024/**/*.parquet')
WHERE event_date >= '2024-01-01'
GROUP BY category
ORDER BY total_revenue DESC
''').fetchdf()
print(result)
# ローカルファイルの処理(メモリに乗らない大容量も対応)
conn.execute('''
CREATE TABLE events AS
SELECT * FROM read_csv_auto('/data/events/*.csv')
''')
# Pandas DataFrameとの連携
import pandas as pd
df = pd.read_parquet("large_file.parquet") # メモリを節約
result = conn.execute("SELECT * FROM df WHERE value > 1000").fetchdf()
# 永続化DBファイルとして使用
db = duckdb.connect("analytics.duckdb")
db.execute("CREATE TABLE IF NOT EXISTS metrics AS SELECT * FROM 'metrics.parquet'")
機能比較表
| 比較項目 | ClickHouse | DuckDB | Apache Druid |
|---|---|---|---|
| デプロイ | サーバー型 | インプロセス | サーバー型 |
| 最大規模 | 数ペタバイト | 数テラバイト | 数ペタバイト |
| リアルタイム投入 | ✅(最速) | ❌ | ✅ |
| SQL互換 | ✅ | ✅(完全) | ✅ |
| Parquet直接クエリ | ✅ | ✅(最も簡単) | ❌ |
| GitHub Stars | 38k+ | 26k+ | 14k+ |
分析データの可視化にはDevOpsカテゴリ/categories/devopsのGrafana・MetabaseをClickHouseデータソースとして接続します。データパイプライン(ETL)はDevOpsカテゴリ/categories/devopsのAirbyte・dltでClickHouseにデータを投入するのが一般的です。
FAQ
Q. ClickHouseとPostgreSQLのパフォーマンスはどのくらい違いますか?
A. OLAPクエリ(集計・フルスキャン)での比較: PostgreSQL: 1億行のSELECT+GROUP BYに数十秒〜数分。行ベースのストレージのためOLAPが苦手。ClickHouse: 同じクエリが数十ミリ秒〜数秒。カラムナストレージ+ベクタライズ処理+圧縮が効く。ただしOLTPトランザクション(単一行のUPDATE/DELETE)はClickHouseが苦手(MergeTree構造のため即時更新コスト高)。用途: トランザクション(注文・在庫・ユーザー認証)はPostgreSQL/Supabase、分析・ログ・メトリクス集計はClickHouseという使い分けが最適です。
Q. DuckDBでBigQueryのコストを削減するには?
A. BigQueryのデータをParquet形式でGCSまたはS3にエクスポート→DuckDBでローカルまたはEC2で分析という構成でBigQueryのクエリ課金を削減できます。具体的: ①BigQuery→GCSエクスポート(EXPORT DATA OPTIONS (format='PARQUET', uri='gs://bucket/*.parquet'))②EC2/GCEでDuckDBを使ってParquetを分析(SELECT ... FROM read_parquet('gs://bucket/*.parquet'))③繰り返す分析はDuckDBの永続DBにINSERTしてキャッシュ。BigQueryのクエリ料金は$5/TB。1TBのデータを毎日10回フルスキャンすると月$1500。DuckDBで同等の分析をEC2($0.1/時間)で行うと月$72以下になります。
Q. ClickHouseをSupabaseと組み合わせてリアルタイムダッシュボードを作るには?
A. Supabase(PostgreSQL)のイベントをClickHouseにストリーミングする構成が一般的です。①Supabaseのログ/イベントテーブルにAFTER INSERTトリガーを設定②PostgRESTまたはSupabase Edge FunctionがClickHouseのHTTP API(port 8123)にイベントをPOST③ClickHouseがMaterialized Viewで集計を事前計算④GrafanaがClickHouseデータソースを使ってダッシュボードを表示。低レイテンシーが必要な場合はKafka(またはRedpanda)をバッファとして挟む構成も使われます。
Q. DuckDBはサーバーレス環境(Vercel)で使えますか?
A. 限定的です。DuckDBはインプロセスライブラリのためNode.js/Python環境に組み込めますが、Vercel Serverless Functions(128MB〜3GBメモリ)では大容量データの処理は難しいです。推奨: ①小規模(〜100MB)のデータ分析ならVercel Functions内でDuckDBを使える②大規模データはClickHouseサーバーをVercelから呼び出す③DuckDB WASMはブラウザで動くためクライアントサイドの軽量分析に使える。DuckDB WASMを使えばクライアントサイドでParquet/CSV分析ツールをVercelにデプロイできます。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| 大規模ログ・リアルタイム・本番OLAP | ClickHouse |
| ローカル分析・Pandas代替・Parquet直接処理 | DuckDB |
| リアルタイムOLAP・大規模ダッシュボード・Kafka統合 | Apache Druid |