> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# パフォーマンスモード (compat_mode)

> 最大のスループットを実現するために、pandas互換性によるオーバーヘッドを無効にするSQLファーストのパフォーマンスモード

DataStoreには、出力をpandas互換向けに整形するか、Raw SQLのパフォーマンス向けに最適化するかを制御する2つの互換性モードがあります。

<div id="overview">
  ## 概要
</div>

| Mode | `compat_mode` value | Description |
| - | - | - |
| **Pandas** (デフォルト) | `"pandas"` | pandas の動作との完全な互換性。行順を保持し、MultiIndex、set\_index、dtype の補正、安定ソート時のタイブレーク、`-If`/`isNaN` ラッパーに対応します。 |
| **Performance** | `"performance"` | SQLファーストで実行します。pandas 互換性のためのオーバーヘッドをすべて排除。最大のスループットを実現しますが、結果の構造が pandas と異なる場合があります。 |

<div id="what-it-disables">
  ### パフォーマンスモードで無効化される機能
</div>

| Overhead | Pandas mode behavior | Performance mode behavior |
| - | - | - |
| **行順序の保持** | `_row_id` の挿入、`rowNumberInAllBlocks()`、`__orig_row_num__` のサブクエリ | 無効 — 行順は保証されません |
| **安定ソートのタイブレーク** | `rowNumberInAllBlocks() ASC` を ORDER BY に追加 | 無効 — 同順位の並び順は任意になる場合があります |
| **Parquet の preserve\_order** | `input_format_parquet_preserve_order=1` | 無効 — Parquet の並列読み取りが可能になります |
| **GroupBy の自動 ORDER BY** | `ORDER BY group_key` を追加 (pandas のデフォルト `sort=True`) | 無効 — グループは任意の順序で返されます |
| **GroupBy の dropna WHERE** | `WHERE key IS NOT NULL` を追加 (pandas のデフォルト `dropna=True`) | 無効 — NULL のグループも含まれます |
| **GroupBy の set\_index** | グループキーをインデックスとして設定 | 無効 — グループキーはカラムのままになります |
| **MultiIndex カラム** | `agg({'col': ['sum','mean']})` は MultiIndex カラムを返します | 無効 — フラットなカラム名 (`col_sum`, `col_mean`) になります |
| **`-If`/`isNaN` ラッパー** | skipna のために `sumIf(col, NOT isNaN(col))` を使用 | 無効 — 単純な `sum(col)` (ClickHouse はネイティブで NULL をスキップ) |
| **count に対する `toInt64`** | pandas の int64 に合わせるために `toInt64(count())` を使用 | 無効 — ネイティブ SQL の Dtype が返されます |
| **全 NaN の sum に対する `fillna(0)`** | すべて NaN の sum は 0 を返す (pandas の動作) | 無効 — NULL を返します |
| **Dtype 補正** | `abs()` の unsigned→signed など | 無効 — ネイティブ SQL の Dtype |
| **インデックスの保持** | SQL 実行後に元のインデックスを復元 | 無効 |
| **`first()`/`last()`** | `argMin/argMax(col, rowNumberInAllBlocks())` | `any(col)` / `anyLast(col)` — 高速ですが非決定論的です |
| **単一 SQL 集約** | ColumnExpr の groupby は中間 DataFrame をマテリアライズします | 遅延実行の処理チェーンに `LazyGroupByAgg` を挿入 — 単一の SQL クエリ |

***

<div id="enabling">
  ## パフォーマンスモードを有効にする
</div>

<div id="using-config">
  ### configオブジェクトを使用する
</div>

```python theme={null}
from chdb.datastore.config import config

# Enable performance mode
config.use_performance_mode()

# Back to pandas compatibility
config.use_pandas_compat()

# Check current mode
print(config.compat_mode)  # 'pandas' or 'performance'
```

<div id="using-functions">
  ### モジュールレベルの関数を使用する
</div>

```python theme={null}
from chdb.datastore.config import set_compat_mode, CompatMode, is_performance_mode

# Enable performance mode
set_compat_mode(CompatMode.PERFORMANCE)

# Check
print(is_performance_mode())  # True

# Back to default
set_compat_mode(CompatMode.PANDAS)
```

<div id="using-imports">
  ### 便利なインポートの利用
</div>

```python theme={null}
from chdb import use_performance_mode, use_pandas_compat

use_performance_mode()
# ... high-performance operations ...
use_pandas_compat()
```

<Note>
  パフォーマンスモードを有効にすると、実行エンジンは自動的に `chdb` に設定されます。`config.use_chdb()` を別途呼び出す必要はありません。
</Note>

***

<div id="when-to-use">
  ## パフォーマンスモードを使うべき場面
</div>

**次のような場合は、パフォーマンスモードを使用してください。**

* 大規模なデータセット (数十万〜数百万行) を処理する場合
* 集約処理の多いワークロード (groupby、sum、mean、count) を実行する場合
* 行順が重要でない場合 (例: 集計結果、レポート、ダッシュボード)
* SQL のスループットを最大化し、オーバーヘッドを最小限に抑えたい場合
* メモリ使用量が気になる場合 (Parquet の並列読み取り、中間 DataFrame なし)

**次のような場合は、pandasモードのままにしてください。**

* pandas と完全に同じ挙動 (行順、MultiIndex、dtypes) が必要な場合
* `first()`/`last()` が実際の最初/最後の行を返すことに依存している場合
* 行順に依存する `shift()`、`diff()`、`cumsum()` を使用する場合
* DataStore の出力を pandas と比較するテストを作成している場合

***

<div id="behavior-differences">
  ## 挙動の違い
</div>

<div id="row-order">
  ### 行の順序
</div>

パフォーマンスモードでは、どの操作でも行の順序は**保証されません**。これには、次のものが含まれます。

* Filter の結果
* GroupBy の集計結果
* 明示的に `sort_values()` を指定しない `head()` / `tail()`
* `first()` / `last()` の集計結果

順序どおりの結果が必要な場合は、明示的に `sort_values()` を追加してください。

```python theme={null}
config.use_performance_mode()

ds = pd.read_csv("data.csv")

# Unordered (fast)
result = ds.groupby("region")["revenue"].sum()

# Ordered (still fast, just adds ORDER BY)
result = ds.groupby("region")["revenue"].sum().sort_values()
```

<div id="groupby-results">
  ### GroupBy の結果
</div>

| 観点 | Pandasモード | パフォーマンスモード |
| - | - | - |
| グループキーの位置 | インデックス (`set_index`経由) | 通常のカラム |
| グループの順序 | キーでソート (デフォルト) | 任意の順序 |
| NULL のグループ | 除外 (デフォルトは`dropna=True`) | 含まれる |
| カラムのフォーマット | 複数集約では MultiIndex | フラットな名前 (`col_func`) |
| `first()`/`last()` | 決定論的 (行の順序) | 非決定論的 (`any()`/`anyLast()`) |

<div id="aggregation">
  ### 集計
</div>

```python theme={null}
config.use_performance_mode()

# Sum of all-NaN group returns NULL (not 0)
# Count returns native uint64 (not forced int64)
# No -If wrappers: sum() instead of sumIf()
result = ds.groupby("cat")["val"].sum()
```

<div id="single-sql">
  ### 単一SQLでの実行
</div>

パフォーマンスモードでは、`ColumnExpr` の groupby 集計 (例: `ds[condition].groupby('col')['val'].sum()`) は、pandasモードで使われる 2 段階の処理ではなく、**単一のSQLクエリ**として実行されます。

```python theme={null}
config.use_performance_mode()

# Pandas mode: two SQL queries (filter → materialize → groupby)
# Performance mode: one SQL query (WHERE + GROUP BY in same query)
result = ds[ds["rating"] > 3.5].groupby("category")["revenue"].sum()

# Generated SQL (single query):
# SELECT category, sum(revenue) FROM data WHERE rating > 3.5 GROUP BY category
```

これにより、中間DataFrameを実体化する必要がなくなり、メモリ使用量と実行時間を大幅に削減できます。

***

<div id="vs-execution-engine">
  ## 実行エンジンとの比較
</div>

パフォーマンスモード (`compat_mode`) と実行エンジン (`execution_engine`) は、**それぞれ独立した設定軸**です。

| Config | Controls | Values |
| - | - | - |
| `execution_engine` | **どのエンジン**で計算を実行するか | `auto`, `chdb`, `pandas` |
| `compat_mode` | pandas 互換性のために出力を整形する**かどうか** | `pandas`, `performance` |

`compat_mode='performance'` を設定すると、`execution_engine='chdb'` も自動的に設定されます。これは、パフォーマンスモードが SQL 実行向けに設計されているためです。

```python theme={null}
from chdb.datastore.config import config

# These are independent
config.use_chdb()              # Force chDB engine, keep pandas compat
config.use_performance_mode()  # Force chDB + remove pandas overhead
```

***

<div id="testing">
  ## パフォーマンスモードでのテスト
</div>

パフォーマンスモード向けのテストを作成する際は、結果の行順やデータ構造のフォーマットが pandas と異なる場合があります。次の方法を使用してください。

<div id="sort-then-compare">
  ### ソートして比較 (集計、フィルター)
</div>

```python theme={null}
# Sort both sides by the same columns before comparing
ds_result = ds.groupby("cat")["val"].sum()
pd_result = pd_df.groupby("cat")["val"].sum()

ds_sorted = ds_result.sort_index()
pd_sorted = pd_result.sort_index()
np.testing.assert_array_equal(ds_sorted.values, pd_sorted.values)
```

<div id="value-range-check">
  ### 値範囲チェック (先頭/末尾)
</div>

```python theme={null}
# first() with any() returns an arbitrary element from the group
result = ds.groupby("cat")["val"].first()
for group_key in groups:
    assert result.loc[group_key] in group_values[group_key]
```

<div id="schema-and-count">
  ### スキーマと件数 (ORDER BY なしの LIMIT)
</div>

```python theme={null}
# head() without sort_values: row set is non-deterministic
result = ds.head(5)
assert len(result) == 5
assert set(result.columns) == expected_columns
```

***

<div id="best-practices">
  ## ベストプラクティス
</div>

<div id="enable-early">
  ### 1. スクリプトの冒頭で有効化する
</div>

```python theme={null}
from chdb.datastore.config import config

config.use_performance_mode()

# All subsequent operations benefit
ds = pd.read_parquet("data.parquet")
result = ds[ds["amount"] > 100].groupby("region")["amount"].sum()
```

<div id="explicit-sort">
  ### 2. 順序が重要な場合は明示的にソートを指定する
</div>

```python theme={null}
# For display or downstream processing that expects order
result = (ds
    .groupby("region")["revenue"].sum()
    .sort_values(ascending=False)
)
```

<div id="batch-etl">
  ### 3. バッチ/ETLワークロードで使用する
</div>

```python theme={null}
config.use_performance_mode()

# ETL pipeline — order doesn't matter, throughput does
summary = (ds
    .filter(ds["date"] >= "2024-01-01")
    .groupby(["region", "product"])
    .agg({"revenue": "sum", "quantity": "sum", "rating": "mean"})
)
summary.to_df().to_parquet("summary.parquet")
```

<div id="switch-modes">
  ### 4. セッション内でモードを切り替える
</div>

```python theme={null}
# Performance mode for heavy computation
config.use_performance_mode()
aggregated = ds.groupby("cat")["val"].sum()

# Back to pandas mode for exact-match comparison
config.use_pandas_compat()
detailed = ds[ds["val"] > 100].head(10)
```

***

<div id="related">
  ## 関連ドキュメント
</div>

* [実行エンジン](/ja/chdb/configuration/execution-engine) — 実行エンジンの選択 (auto/chdb/pandas)
* [Performance Guide](/ja/chdb/guides/pandas-performance) — 一般的な最適化のポイント
* [pandas との主な違い](/ja/chdb/guides/pandas-differences) — 動作の違い
