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

# Mode performance (compat_mode)

> Mode performance orienté SQL qui supprime le surcoût de compatibilité avec pandas pour un débit maximal

DataStore dispose de deux modes de compatibilité qui déterminent si la sortie est mise en forme pour être compatible avec pandas ou optimisée pour les performances du Raw SQL.

<div id="overview">
  ## Vue d’ensemble
</div>

| Mode                    | valeur de `compat_mode` | Description                                                                                                                                                                                           |
| ----------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pandas** (par défaut) | `"pandas"`              | Compatibilité complète avec le comportement de pandas. Ordre des lignes préservé, MultiIndex, set\_index, corrections de dtype, règles de départage pour un tri stable, wrappers `-If`/`isNaN`.       |
| **Performance**         | `"performance"`         | Exécution orientée SQL. Toute la surcharge liée à la compatibilité avec pandas est supprimée. Débit maximal, mais les résultats peuvent présenter des différences structurelles par rapport à pandas. |

<div id="what-it-disables">
  ### Ce que désactive le Mode Performance
</div>

| Surcoût                                           | Comportement du mode Pandas                                                        | Comportement du Mode Performance                                                  |
| ------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| **Préservation de l’ordre des lignes**            | Injection de `_row_id`, `rowNumberInAllBlocks()`, sous-requêtes `__orig_row_num__` | Désactivé — l’ordre des lignes n’est pas garanti                                  |
| **Départage en cas d’égalité pour un tri stable** | `rowNumberInAllBlocks() ASC` ajouté à ORDER BY                                     | Désactivé — les ex æquo peuvent apparaître dans un ordre arbitraire               |
| **`preserve_order` de Parquet**                   | `input_format_parquet_preserve_order=1`                                            | Désactivé — lecture parallèle de Parquet autorisée                                |
| **ORDER BY automatique de GroupBy**               | `ORDER BY group_key` ajouté (valeur par défaut de pandas : `sort=True`)            | Désactivé — les groupes sont renvoyés dans un ordre arbitraire                    |
| **WHERE `dropna` de GroupBy**                     | `WHERE key IS NOT NULL` ajouté (valeur par défaut de pandas : `dropna=True`)       | Désactivé — les groupes NULL sont inclus                                          |
| **`set_index` de GroupBy**                        | Les clés de groupe sont définies comme index                                       | Désactivé — les clés de groupe restent des colonnes                               |
| **Colonnes MultiIndex**                           | `agg({'col': ['sum','mean']})` renvoie des colonnes MultiIndex                     | Désactivé — noms de colonnes aplatis (`col_sum`, `col_mean`)                      |
| **Wrappers `-If`/`isNaN`**                        | `sumIf(col, NOT isNaN(col))` pour `skipna`                                         | Désactivé — `sum(col)` simple (ClickHouse ignore nativement les NULL)             |
| **`toInt64` sur `count`**                         | `toInt64(count())` pour correspondre à `pandas int64`                              | Désactivé — type SQL natif renvoyé                                                |
| **`fillna(0)` pour une somme entièrement NaN**    | La somme de valeurs toutes NaN renvoie 0 (comportement pandas)                     | Désactivé — renvoie NULL                                                          |
| **Corrections de type**                           | `abs()` non signé→signé, etc.                                                      | Désactivé — types SQL natifs                                                      |
| **Préservation de l’index**                       | Restaure l’index d’origine après l’exécution SQL                                   | Désactivé                                                                         |
| **`first()`/`last()`**                            | `argMin/argMax(col, rowNumberInAllBlocks())`                                       | `any(col)` / `anyLast(col)` — plus rapide mais non déterministe                   |
| **Agrégation en une seule requête SQL**           | Le `groupby` de `ColumnExpr` matérialise un `DataFrame` intermédiaire              | Injecte `LazyGroupByAgg` dans la chaîne d’opérations lazy — une seule requête SQL |

***

<div id="enabling">
  ## Activer le mode Performance
</div>

<div id="using-config">
  ### Utilisation de l’objet 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">
  ### Utilisation des fonctions définies au niveau du module
</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">
  ### Utilisation des imports simplifiés
</div>

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

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

<Note>
  Activer le mode performance définit automatiquement le moteur d’exécution sur `chdb`. Vous n’avez pas besoin d’appeler `config.use_chdb()` séparément.
</Note>

***

<div id="when-to-use">
  ## Quand utiliser le mode Performance
</div>

**Utilisez le mode Performance dans les cas suivants :**

* Vous traitez de grands jeux de données (de centaines de milliers à plusieurs millions de lignes)
* Vous exécutez des charges de travail riches en agrégations (groupby, sum, mean, count)
* L’ordre des lignes n’a pas d’importance (par exemple, résultats agrégés, rapports, tableaux de bord)
* Vous recherchez un débit SQL maximal avec une surcharge minimale
* L’utilisation de la mémoire est un enjeu (lecture parallèle de Parquet, sans DataFrames intermédiaires)

**Restez en mode pandas dans les cas suivants :**

* Vous avez besoin du comportement exact de pandas (ordre des lignes, MultiIndex, dtypes)
* Vous comptez sur `first()`/`last()` pour renvoyer réellement la première ou la dernière ligne
* Vous utilisez `shift()`, `diff()`, `cumsum()` qui dépendent de l’ordre des lignes
* Vous écrivez des tests qui comparent la sortie de DataStore à celle de pandas

***

<div id="behavior-differences">
  ## Différences de comportement
</div>

<div id="row-order">
  ### Ordre des lignes
</div>

En mode performance, l’ordre des lignes n’est **pas garanti**, quelle que soit l’opération. Cela inclut :

* Les résultats de filtrage
* Les résultats d’agrégation de GroupBy
* `head()` / `tail()` sans `sort_values()` explicite
* Les agrégations `first()` / `last()`

Si vous avez besoin de résultats triés, ajoutez un `sort_values()` explicite :

```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">
  ### Résultats de GroupBy
</div>

| Aspect                                | Mode Pandas                               | Mode Performance                       |
| ------------------------------------- | ----------------------------------------- | -------------------------------------- |
| Emplacement de la clé de regroupement | Index (via `set_index`)                   | Colonne classique                      |
| Ordre des groupes                     | Trié par clé (par défaut)                 | Ordre arbitraire                       |
| Groupes NULL                          | Exclus (par défaut `dropna=True`)         | Inclus                                 |
| Format des colonnes                   | MultiIndex pour les agrégations multiples | Noms simples (`col_func`)              |
| `first()`/`last()`                    | Déterministe (ordre des lignes)           | Non déterministe (`any()`/`anyLast()`) |

<div id="aggregation">
  ### Agrégation
</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">
  ### Exécution en une seule requête SQL
</div>

En mode performance, l’agrégation groupby `ColumnExpr` (par ex., `ds[condition].groupby('col')['val'].sum()`) s’exécute sous la forme d’une **seule requête SQL**, au lieu du processus en deux étapes utilisé en mode pandas :

```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
```

Cela évite la matérialisation intermédiaire du DataFrame et peut réduire considérablement l’utilisation de la mémoire ainsi que le temps d’exécution.

***

<div id="vs-execution-engine">
  ## Comparaison avec le moteur d'exécution
</div>

Le mode Performance (`compat_mode`) et le moteur d'exécution (`execution_engine`) sont **deux axes de configuration indépendants** :

| Config             | Contrôle                                                             | Valeurs                  |
| ------------------ | -------------------------------------------------------------------- | ------------------------ |
| `execution_engine` | **Quel moteur** exécute le calcul                                    | `auto`, `chdb`, `pandas` |
| `compat_mode`      | **S'il faut** reformater la sortie pour la compatibilité avec pandas | `pandas`, `performance`  |

Définir `compat_mode='performance'` règle automatiquement `execution_engine='chdb'`, car le mode Performance est conçu pour l'exécution 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">
  ## Tests avec le mode Performance
</div>

Lors de l’écriture de tests avec le mode Performance, les résultats peuvent différer de ceux de pandas quant à l’ordre des lignes et au format structurel. Utilisez les stratégies suivantes :

<div id="sort-then-compare">
  ### Tri puis comparaison (agrégations, filtres)
</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">
  ### Vérification de l’intervalle de valeurs (première/dernière)
</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">
  ### Schéma et comptage (LIMIT sans ORDER BY)
</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">
  ## Bonnes pratiques
</div>

<div id="enable-early">
  ### 1. Activez-la au début de votre script
</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. Ajoutez un tri explicite lorsque l’ordre est important
</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. À utiliser pour les charges de travail de type batch/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. Passer d’un mode à l’autre au sein d’une session
</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">
  ## Documentation connexe
</div>

* [Moteur d’exécution](/fr/products/chdb/configuration/execution-engine) — Sélection du moteur (auto/chdb/pandas)
* [Guide des performances](/fr/products/chdb/guides/pandas-performance) — Conseils généraux d’optimisation
* [Principales différences avec pandas](/fr/products/chdb/guides/pandas-differences) — Différences de comportement
