デバッグツールの概要
| ツール | 目的 | 使用する場面 |
|---|---|---|
explain() | 実行計画を確認 | 実行される SQL の内容を把握する |
| プロファイラ | パフォーマンスを測定 | 遅い処理を特定する |
| ログ | 実行の詳細を確認 | 想定外の動作をデバッグする |
クイック判断表
| 必要なもの | ツール | コマンド |
|---|---|---|
| 実行計画を確認 | explain() | ds.explain() |
| パフォーマンスを測定 | プロファイラ | config.enable_profiling() |
| SQLクエリをデバッグ | ログ | config.enable_debug() |
| 上記すべて | 組み合わせ | 以下を参照 |
クイックセットアップ
すべてのデバッグ機能を有効にする
from chdb import datastore as pd
from chdb.datastore.config import config
# すべてのデバッグを有効化
config.enable_debug() # 詳細ロギング
config.enable_profiling() # パフォーマンス追跡
ds = pd.read_csv("data.csv")
result = ds.filter(ds['age'] > 25).groupby('city').agg({'salary': 'mean'})
# 実行計画を表示
result.explain()
# プロファイラレポートを取得
from chdb.datastore.config import get_profiler
profiler = get_profiler()
profiler.report()
explain() メソッド
Query
ds = pd.read_csv("data.csv")
query = (ds
.filter(ds['amount'] > 1000)
.groupby('region')
.agg({'amount': ['sum', 'mean']})
)
# プランを表示
query.explain()
Response
Pipeline:
Source: file('data.csv', 'CSVWithNames')
Filter: amount > 1000
GroupBy: region
Aggregate: sum(amount), avg(amount)
Generated SQL:
SELECT region, SUM(amount) AS sum, AVG(amount) AS mean
FROM file('data.csv', 'CSVWithNames')
WHERE amount > 1000
GROUP BY region
プロファイリング
Query
from chdb.datastore.config import config, get_profiler
# プロファイリングを有効化
config.enable_profiling()
# 操作を実行
ds = pd.read_csv("large_data.csv")
result = (ds
.filter(ds['amount'] > 100)
.groupby('category')
.agg({'amount': 'sum'})
.sort('sum', ascending=False)
.head(10)
.to_df()
)
# レポートを表示
profiler = get_profiler()
profiler.report(min_duration_ms=0.1)
Response
パフォーマンスレポート
==================
ステップ 所要時間 呼び出し回数
---- -------- -----
read_csv 1.234s 1
filter 0.002s 1
groupby 0.001s 1
agg 0.089s 1
sort 0.045s 1
head 0.001s 1
to_df (SQL execution) 0.567s 1
---- -------- -----
合計 1.939s 7
ログ
from chdb.datastore.config import config
# デバッグログを有効化
config.enable_debug()
# 操作を実行すると、以下がログに表示されます:
# - 生成されたSQLクエリ
# - 使用された実行エンジン
# - cacheのヒット/ミス
# - タイミング情報
DEBUG - DataStore: Creating from file 'data.csv'
DEBUG - Query: SELECT region, SUM(amount) FROM ... WHERE amount > 1000 GROUP BY region
DEBUG - Engine: Using chdb for aggregation
DEBUG - Execution time: 0.089s
DEBUG - Cache: Storing result (key: abc123)
よくあるデバッグのシナリオ
1. クエリが期待どおりの結果を返さない
# ステップ1: 実行計画を確認する
query = ds.filter(ds['age'] > 25).groupby('city').sum()
query.explain(verbose=True)
# ステップ2: SQLを確認するためにログを有効にする
config.enable_debug()
# ステップ3: 実行してログを確認する
result = query.to_df()
2. クエリの実行が遅い
# ステップ1: プロファイリングを有効にする
config.enable_profiling()
# ステップ2: クエリを実行する
result = process_data()
# ステップ3: プロファイラのレポートを確認する
profiler = get_profiler()
profiler.report()
# ステップ4: 遅い処理を特定して最適化する
3. Engine 選択を理解する
# 詳細ロギングを有効にする
config.enable_debug()
# 操作を実行する
result = ds.filter(ds['x'] > 10).apply(custom_func)
# ログには各操作で使用されたエンジンが表示される:
# DEBUG - filter: chdb エンジンを使用
# DEBUG - apply: pandas エンジンを使用(カスタム関数)
4. cache に関する問題のデバッグ
# キャッシュ操作を確認するためにデバッグを有効化
config.enable_debug()
# 初回実行
result1 = ds.filter(ds['x'] > 10).to_df()
# LOG: キャッシュミス、クエリを実行中
# 2回目の実行(cacheを使用するはず)
result2 = ds.filter(ds['x'] > 10).to_df()
# LOG: キャッシュヒット、キャッシュ済み結果を返却
# 期待通りにキャッシュされない場合は以下を確認:
# - 操作は同一か?
# - cacheは有効か? config.cache_enabled
ベストプラクティス
1. デバッグは本番環境ではなく開発環境で行う
# 開発環境
config.enable_debug()
config.enable_profiling()
# 本番環境
config.set_log_level(logging.WARNING)
config.set_profiling_enabled(False)
2. 大規模なクエリを実行する前に explain() を活用する
# クエリを構築する
query = ds.filter(...).groupby(...).agg(...)
# まず実行計画を確認する
query.explain()
# 実行計画に問題がなければ実行する
result = query.to_df()
3. 最適化の前にプロファイリングを行う
# 遅い箇所を推測せず、計測する
config.enable_profiling()
result = your_pipeline()
get_profiler().report()
4. 結果が正しくない場合は SQL を確認する
# 生成された SQL を表示する
print(query.to_sql())
# 期待される SQL と比較する
# ClickHouse で直接 SQL を実行して確認する
デバッグツールのまとめ
| ツール | コマンド | 出力 |
|---|---|---|
| 実行プランの表示 | ds.explain() | 実行ステップ + SQL |
| 詳細な実行プラン | ds.explain(verbose=True) | + メタデータ |
| SQL の表示 | ds.to_sql() | SQL クエリ文字列 |
| デバッグを有効にする | config.enable_debug() | 詳細なログ |
| プロファイリングを有効にする | config.enable_profiling() | タイミングデータ |
| プロファイラレポート | get_profiler().report() | パフォーマンスの概要 |
| プロファイラをクリア | get_profiler().reset() | タイミングデータをクリア |
次のステップ
- explain() メソッド - 実行計画の詳細な解説
- プロファイリングガイド - パフォーマンス計測
- ログ設定 - ログレベルとフォーマットの設定