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

# Guía de rendimiento

> Consejos para optimizar el rendimiento de DataStore frente a pandas

DataStore ofrece mejoras significativas de rendimiento frente a pandas en muchas operaciones. Esta guía explica por qué y cómo optimizar sus cargas de trabajo.

<div id="why-faster">
  ## Por qué DataStore es más rápido
</div>

<div id="sql-pushdown">
  ### 1. SQL Pushdown
</div>

Las operaciones se ejecutan en la fuente de datos:

```python theme={null}
# pandas: Carga TODOS los datos y luego filtra en memoria
df = pd.read_csv("huge.csv")       # Carga 10 GB
df = df[df['year'] == 2024]        # Filtra en Python

# DataStore: Filtra en el origen
ds = pd.read_csv("huge.csv")       # Solo metadatos
ds = ds[ds['year'] == 2024]        # Filtra en SQL
df = ds.to_df()                    # Solo carga los datos filtrados
```

<div id="column-pruning">
  ### 2. Poda de columnas
</div>

Solo se leen las columnas necesarias:

```python theme={null}
# DataStore: Solo lee las columnas name, age
ds = pd.read_parquet("wide_table.parquet")
result = ds.select('name', 'age').to_df()

# vs pandas: Lee las 100 columnas y luego selecciona
```

<div id="lazy-evaluation">
  ### 3. Evaluación diferida
</div>

Varias operaciones se traducen a una sola consulta:

```python theme={null}
# DataStore: Una consulta SQL optimizada
result = (ds
    .filter(ds['amount'] > 100)
    .groupby('region')
    .agg({'amount': 'sum'})
    .sort('sum', ascending=False)
    .head(10)
    .to_df()
)

# Se convierte en:
# SELECT region, SUM(amount) FROM data
# WHERE amount > 100
# GROUP BY region ORDER BY sum DESC LIMIT 10
```

***

<div id="benchmark">
  ## Benchmark: DataStore vs pandas
</div>

<div id="test-environment">
  ### Entorno de prueba
</div>

* Datos: 10 millones de filas
* Hardware: portátil estándar
* Formato de archivo: CSV

<div id="results">
  ### Resultados
</div>

| Operación                | pandas (ms) | DataStore (ms) | Ganador                |
| ------------------------ | ----------- | -------------- | ---------------------- |
| Conteo con GroupBy       | 347         | 17             | **DataStore (19.93x)** |
| Operaciones combinadas   | 1,535       | 234            | **DataStore (6.56x)**  |
| Canalización compleja    | 2,047       | 380            | **DataStore (5.39x)**  |
| MultiFilter+Sort+Head    | 1,963       | 366            | **DataStore (5.36x)**  |
| Filter+Sort+Head         | 1,537       | 350            | **DataStore (4.40x)**  |
| Head/Limit               | 166         | 45             | **DataStore (3.69x)**  |
| Ultra complejo (10+ ops) | 1,070       | 338            | **DataStore (3.17x)**  |
| Agregación con GroupBy   | 406         | 141            | **DataStore (2.88x)**  |
| Select+Filter+Sort       | 1,217       | 443            | **DataStore (2.75x)**  |
| Filter+GroupBy+Sort      | 466         | 184            | **DataStore (2.53x)**  |
| Filter+Select+Sort       | 1,285       | 533            | **DataStore (2.41x)**  |
| Sort (simple)            | 1,742       | 1,197          | **DataStore (1.45x)**  |
| Filter (simple)          | 276         | 526            | Comparable             |
| Sort (múltiple)          | 947         | 1,477          | Comparable             |

<div id="insights">
  ### Puntos clave
</div>

1. **Operaciones de GroupBy**: DataStore es hasta **19.93x más rápido**
2. **Canalizaciones complejas**: DataStore es **5-6x más rápido** (gracias al pushdown en SQL)
3. **Operaciones de slicing simples**: rendimiento comparable; diferencia insignificante
4. **Caso de uso ideal**: operaciones de varios pasos con groupby/agregación
5. **Zero-copy**: `to_df()` no tiene sobrecarga por conversión de datos

***

<div id="when-datastore-wins">
  ## Cuándo conviene usar DataStore
</div>

<div id="heavy-aggregations">
  ### Agregaciones exigentes
</div>

```python theme={null}
# DataStore destaca: 19.93x más rápido
result = ds.groupby('category')['amount'].sum()
```

<div id="complex-pipelines">
  ### Canalizaciones complejas
</div>

```python theme={null}
# DataStore sobresale: 5-6x más rápido
result = (ds
    .filter(ds['date'] >= '2024-01-01')
    .filter(ds['amount'] > 100)
    .groupby('region')
    .agg({'amount': ['sum', 'mean', 'count']})
    .sort('sum', ascending=False)
    .head(20)
)
```

<div id="large-file-processing">
  ### Procesamiento de archivos de gran tamaño
</div>

```python theme={null}
# DataStore: Solo carga lo que necesitas
ds = pd.read_parquet("huge_file.parquet")
result = ds.filter(ds['id'] == 12345).to_df()  # ¡Rápido!
```

<div id="multiple-column-operations">
  ### Operaciones con varias columnas
</div>

```python theme={null}
# DataStore: Combina en un único SQL
ds['total'] = ds['price'] * ds['quantity']
ds['is_large'] = ds['total'] > 1000
ds = ds.filter(ds['is_large'])
```

***

<div id="when-pandas-wins">
  ## Cuándo pandas ofrece un rendimiento comparable
</div>

En la mayoría de los casos, DataStore iguala o supera el rendimiento de pandas. Sin embargo, pandas puede ser ligeramente más rápido en estos casos concretos:

<div id="small-datasets">
  ### Conjuntos de datos pequeños (\<1,000 filas)
</div>

```python theme={null}
# Para conjuntos de datos muy pequeños, la sobrecarga es mínima en ambos casos
# La diferencia de rendimiento es insignificante
small_df = pd.DataFrame({'x': range(100)})
```

<div id="simple-slice-operations">
  ### Operaciones simples de slicing
</div>

```python theme={null}
# Operaciones de segmentación simples sin agregación
df = df[df['x'] > 10]  # pandas es algo más rápido
ds = ds[ds['x'] > 10]  # DataStore ofrece un rendimiento comparable
```

<div id="custom-python-functions">
  ### Funciones lambda personalizadas de Python
</div>

```python theme={null}
# se requiere pandas para código Python personalizado
def complex_function(row):
    return custom_logic(row)

df['result'] = df.apply(complex_function, axis=1)
```

<Info>
  **Importante**

  Incluso en los casos en que DataStore es "más lento", el rendimiento suele estar **a la altura de pandas**; la diferencia es insignificante en la práctica. Las ventajas de DataStore en operaciones complejas superan con creces estos casos puntuales.

  Para un control más preciso de la ejecución, consulte [Configuración de Execution Engine](/es/products/chdb/configuration/execution-engine).
</Info>

***

<div id="zero-copy">
  ## Integración zero-copy de DataFrames
</div>

DataStore usa **zero-copy** para leer y escribir DataFrames de pandas. Esto significa:

```python theme={null}
# to_df() NO copia datos - es una operación zero-copy
result = ds.filter(ds['x'] > 10).to_df()  # Sin sobrecarga de conversión de datos

# Lo mismo aplica para crear un DataStore desde un DataFrame
ds = DataStore(existing_df)  # Sin copia de datos
```

**Implicaciones clave:**

* `to_df()` es prácticamente gratuito: no hay serialización ni copias de memoria
* Crear un DataStore a partir de un DataFrame de pandas es instantáneo
* La memoria se comparte entre DataStore y las vistas de pandas

***

<div id="tips">
  ## Consejos de optimización
</div>

<div id="use-performance-mode">
  ### 1. Activa el modo de rendimiento para cargas de trabajo intensivas
</div>

Para cargas de trabajo con agregación intensiva en las que no necesitas el formato de salida exacto de pandas (orden de las filas, columnas MultiIndex, correcciones de `dtype`), activa el modo de rendimiento para maximizar el throughput:

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

config.use_performance_mode()

# Ahora todas las operaciones usan ejecución SQL-first sin sobrecarga de pandas:
# - Lectura paralela de Parquet (sin preserve_order)
# - Agregación en una sola consulta SQL (filter+groupby en una sola consulta)
# - Sin sobrecarga por preservación del orden de filas
# - Sin MultiIndex, sin correcciones de dtype
result = (ds
    .filter(ds['amount'] > 100)
    .groupby('region')
    .agg({'amount': ['sum', 'mean', 'count']})
)
```

**Mejora esperada**: Entre 2 y 8 veces más rápido en cargas de trabajo con filter+groupby, y menor uso de memoria con archivos Parquet grandes.

Consulta [Modo de rendimiento](/es/products/chdb/configuration/performance-mode) para obtener todos los detalles.

<div id="use-parquet">
  ### 2. Usa Parquet en lugar de CSV
</div>

```python theme={null}
# CSV: Más lento, lee el archivo completo
ds = pd.read_csv("data.csv")

# Parquet: Más rápido, columnar, comprimido
ds = pd.read_parquet("data.parquet")

# Convierte una vez, benefíciate para siempre
df = pd.read_csv("data.csv")
df.to_parquet("data.parquet")
```

**Mejora esperada**: lecturas entre 3 y 10 veces más rápidas

<div id="filter-early">
  ### 3. Filtra desde el principio
</div>

```python theme={null}
# Correcto: Filtrar primero, luego agregar
result = (ds
    .filter(ds['date'] >= '2024-01-01')  # Reducir datos con anticipación
    .groupby('category')['amount'].sum()
)

# Menos óptimo: Procesar todos los datos
result = (ds
    .groupby('category')['amount'].sum()
    .filter(ds['sum'] > 1000)  # Filtrar demasiado tarde
)
```

<div id="select-only-needed-columns">
  ### 4. Seleccione solo las columnas necesarias
</div>

```python theme={null}
# Bueno: Poda de columnas
result = ds.select('name', 'amount').filter(ds['amount'] > 100)

# Menos óptimo: Todas las columnas cargadas
result = ds.filter(ds['amount'] > 100)  # Carga todas las columnas
```

<div id="leverage-sql-aggregations">
  ### 5. Aprovecha las agregaciones en SQL
</div>

```python theme={null}
# GroupBy es donde DataStore brilla
# ¡Hasta 20x más rápido!
result = ds.groupby('category').agg({
    'amount': ['sum', 'mean', 'count', 'max'],
    'quantity': 'sum'
})
```

<div id="use-head">
  ### 6. Usa head() en lugar de consultas completas
</div>

```python theme={null}
# No cargues el resultado completo si solo necesitas una muestra
result = ds.filter(ds['type'] == 'A').head(100)  # LIMIT 100

# Evita esto para resultados grandes
# result = ds.filter(ds['type'] == 'A').to_df()  # Carga todo
```

<div id="batch-operations">
  ### 7. Operaciones por lotes
</div>

```python theme={null}
# Correcto: Ejecución única
result = ds.filter(ds['x'] > 10).filter(ds['y'] < 100).to_df()

# Incorrecto: Múltiples ejecuciones
result1 = ds.filter(ds['x'] > 10).to_df()  # Ejecutar
result2 = result1[result1['y'] < 100]       # Ejecutar de nuevo
```

<div id="use-explain">
  ### 8. Utiliza explain() para optimizar
</div>

```python theme={null}
# Ver el plan de consulta antes de ejecutar
query = ds.filter(...).groupby(...).agg(...)
query.explain()  # Comprobar si las operaciones se delegan al origen

# Luego ejecutar
result = query.to_df()
```

***

<div id="profiling">
  ## Perfilado de la carga de trabajo
</div>

<div id="enable-profiling">
  ### Activar el perfilado
</div>

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

config.enable_profiling()

# Ejecuta tu workload
result = your_pipeline()

# Ver informe
profiler = get_profiler()
profiler.report()
```

<div id="identify-bottlenecks">
  ### Identificar cuellos de botella
</div>

```text theme={null}
Informe de rendimiento
==================
Paso                    Duración    % Total
----                    --------    -------
SQL execution           2.5s        62.5%     <- ¡Cuello de botella!
read_csv                1.2s        30.0%
Otros                   0.3s        7.5%
```

<div id="compare-approaches">
  ### Comparación de enfoques
</div>

```python theme={null}
# Probar enfoque 1
profiler.reset()
result1 = approach1()
time1 = profiler.get_steps()[-1]['duration_ms']

# Probar enfoque 2
profiler.reset()
result2 = approach2()
time2 = profiler.get_steps()[-1]['duration_ms']

print(f"Approach 1: {time1:.0f}ms")
print(f"Approach 2: {time2:.0f}ms")
```

***

<div id="summary">
  ## Resumen de buenas prácticas
</div>

| Práctica                            | Impacto                                              |
| ----------------------------------- | ---------------------------------------------------- |
| Active el modo de rendimiento       | 2-8x más rápido para cargas de trabajo de agregación |
| Use archivos Parquet                | lecturas 3-10x más rápidas                           |
| Filtre pronto                       | Reduzca el procesamiento de datos                    |
| Seleccione las columnas necesarias  | Reduzca la E/S y el uso de memoria                   |
| Use GroupBy/agregaciones            | Hasta 20x más rápido                                 |
| Agrupe operaciones en lotes         | Evite la ejecución repetida                          |
| Genere un perfil antes de optimizar | Encuentre los cuellos de botella reales              |
| Use explain()                       | Verifique la optimización de la consulta             |
| Use head() para muestras            | Evite escaneos completos de tablas                   |

***

<div id="decision">
  ## Guía rápida de decisión
</div>

| Su carga de trabajo                       | Recomendación                                     |
| ----------------------------------------- | ------------------------------------------------- |
| GroupBy/agregación                        | Use DataStore                                     |
| Canalización compleja de varios pasos     | Use DataStore                                     |
| Archivos grandes con filtros              | Use DataStore                                     |
| Operaciones de slicing simples            | Cualquiera de los dos (rendimiento comparable)    |
| Funciones lambda personalizadas de Python | Use pandas o convierta más tarde                  |
| Datos muy pequeños (\<1,000 filas)        | Cualquiera de los dos (diferencia insignificante) |

<Tip>
  Para seleccionar automáticamente el motor óptimo, use `config.set_execution_engine('auto')` (predeterminado).
  Para obtener el máximo rendimiento en cargas de trabajo de agregación, use `config.use_performance_mode()`.
  Consulte [Execution Engine](/es/products/chdb/configuration/execution-engine) y [Performance Mode](/es/products/chdb/configuration/performance-mode) para obtener más detalles.
</Tip>
