> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentación sobre índices hipotéticos (what-if)

# Índices hipotéticos

Los índices hipotéticos son índices de omisión virtuales limitados al ámbito de la sesión que puedes asociar a una tabla de la familia `MergeTree` sin llegar a construirlos ni almacenarlos. Solo existen dentro de la sesión actual y [`EXPLAIN WHATIF`](/docs/es/reference/statements/explain#explain-whatif) los usa para estimar cómo afectaría un índice de omisión real a una consulta, normalmente la tasa de omisión (la fracción de marcas que podrían omitirse) y un costo aproximado en marcas y bytes.

Usa índices hipotéticos para evaluar posibles índices antes de asumir el costo de materializarlos en disco.

<div id="create-hypothetical-index">
  ## CREATE HYPOTHETICAL INDEX
</div>

```sql theme={null}
CREATE HYPOTHETICAL INDEX [IF NOT EXISTS] name
    ON [db.]table_name (expression) TYPE type[(args)] [GRANULARITY value]
```

La sintaxis refleja `ALTER TABLE ... ADD INDEX`, pero no se crea ni se escribe ningún índice; solo se almacena la descripción del índice en la sesión actual.

* `name` — nombre del índice; debe ser único dentro de `(database, table)` para esta sesión.
* `expression` — la columna o expresión que se va a indexar.
* `TYPE type` — `minmax`, `set(N)`, `bloom_filter(p)`, `ngrambf_v1(...)`, `tokenbf_v1(...)`. `text` y `vector_similarity` no son compatibles y se rechazan al ejecutar `CREATE`, porque la validación real de `ALTER TABLE ... ADD INDEX` depende de configuraciones a nivel de tabla que el almacenamiento limitado a la sesión no puede reproducir.
* `GRANULARITY value` — número de gránulos de datos por gránulo de índice. El valor predeterminado es 1.

La tabla de destino debe ser una tabla de la familia `MergeTree` en una base de datos `Atomic` (debe tener un UUID). Las tablas sin UUID —por ejemplo, en una base de datos `Ordinary` heredada o un `MergeTree` con sintaxis antigua— se rechazan, porque el almacenamiento de sesión identifica los índices hipotéticos mediante el UUID de la tabla.

**Ejemplo**

```sql theme={null}
CREATE HYPOTHETICAL INDEX idx_b ON t (b) TYPE minmax GRANULARITY 1;
```

<div id="evaluating-a-hypothetical-index-with-explain-whatif">
  ## Evaluar un índice hipotético con EXPLAIN WHATIF
</div>

Definir un índice hipotético por sí solo no hace nada; para ver cómo afectaría a una consulta, ejecuta [`EXPLAIN WHATIF`](/docs/es/reference/statements/explain#explain-whatif) sobre un `SELECT` representativo. El estimador informa de la aplicabilidad de cada índice candidato, las marcas que leería, la tasa de omisión resultante y cómo se produjo la estimación (`empirical`, `statistical` o `applicability_only`).

```sql theme={null}
CREATE TABLE t (a UInt64, b UInt64) ENGINE = MergeTree ORDER BY a
SETTINGS index_granularity = 100;

INSERT INTO t SELECT number, number FROM numbers(10000);

CREATE HYPOTHETICAL INDEX idx_b ON t (b) TYPE minmax GRANULARITY 1;

EXPLAIN WHATIF SELECT * FROM t WHERE b = 42;
```

Resultado:

```text theme={null}
Baseline (after PK + partition + existing indexes):
  table:       default.t
  parts:       1
  marks:       100
  est_bytes:   85.52 KiB

With idx_b (minmax, hypothetical):
  status:       applicable
  marks:        1
  est_bytes:    875.00 B
  skip_ratio:   99.0%

Estimation:
  source:           empirical
  empirical_status: ok
  sampled_parts:    1 / 1
  sampled_marks:    100 / 100
  elapsed_us:       631
```

`est_bytes` es una estimación basada en el tamaño medio de las filas de la tabla, por lo que la cifra exacta varía según el almacenamiento y la compresión.

Para omitir el escaneo empírico en memoria y estimar a partir de las [estadísticas de columnas](/docs/es/reference/engines/table-engines/mergetree-family/mergetree#column-statistics), primero defínelas en las columnas pertinentes (están desactivadas de forma predeterminada), espera a que termine la mutación de materialización y, a continuación, desactiva la ruta empírica:

```sql theme={null}
ALTER TABLE t ADD STATISTICS b TYPE TDigest;
ALTER TABLE t MATERIALIZE STATISTICS b SETTINGS mutations_sync = 1;

EXPLAIN WHATIF empirical = 0 SELECT * FROM t WHERE b < 10;
```

```text theme={null}
With idx_b (minmax, hypothetical):
  status:       applicable
  marks:        1
  est_bytes:    1.66 KiB
  skip_ratio:   99.9%

Estimation:
  source:           statistical
  empirical_status: disabled
```

Consulte la referencia de [`EXPLAIN WHATIF`](/docs/es/reference/statements/explain#explain-whatif) para ver el esquema de salida completo y las opciones de configuración.

<div id="drop-hypothetical-index">
  ## DROP HYPOTHETICAL INDEX
</div>

```sql theme={null}
DROP HYPOTHETICAL INDEX [IF EXISTS] name ON [db.]table_name
```

Elimina un índice hipotético de la sesión actual.

<div id="drop-all-hypothetical-indexes">
  ## DROP ALL HYPOTHETICAL INDEXES
</div>

```sql theme={null}
DROP ALL HYPOTHETICAL INDEXES
```

Elimina todos los índices hipotéticos definidos en la sesión actual, sin importar la tabla.

<div id="scope-and-lifetime">
  ## Alcance y duración
</div>

* Los índices hipotéticos existen solo en la **sesión actual**; no son visibles para otras sesiones y se descartan cuando la sesión termina.
* Definir o eliminar uno no crea ningún índice ni afecta nunca a las consultas normales sobre la tabla. La variante empírica de `EXPLAIN WHATIF` sí lee datos de la tabla para construir el índice candidato en memoria, y ese escaneo cuenta para los límites de lectura y las cuotas de la sesión.
* Inspeccione los índices hipotéticos de la sesión actual mediante [`system.hypothetical_indexes`](/docs/es/reference/system-tables/hypothetical_indexes).

<div id="limitations">
  ## Limitaciones
</div>

Los candidatos `text` y `vector_similarity` se rechazan en el momento de `CREATE HYPOTHETICAL INDEX`, porque su validación real depende de ajustes a nivel de tabla que el almacén limitado a la sesión no puede replicar.

`EXPLAIN WHATIF` muestra `status: not_applicable` para consultas con `FINAL` (la poda del índice de omisión interactúa con `PrimaryKeyExpand`) y devuelve `NOT_IMPLEMENTED` cuando la consulta se sirve desde una proyección (un índice de la tabla padre no se materializa en las partes de proyección).

El `skip_ratio` empírico es una **cota superior**: cuenta cada gránulo que sobrevive de forma independiente y no modela la coalescencia de huecos de seek (`merge_tree_min_rows_for_seek` / `merge_tree_min_bytes_for_seek`), ni la combinación de un candidato con un índice de omisión existente bajo un predicado disyuntivo (`OR`). Por lo tanto, un índice materializado real puede leer algo más, o podar en casos en los que la estimación no lo hace.

<div id="required-privileges">
  ## Privilegios requeridos
</div>

`CREATE HYPOTHETICAL INDEX` requiere `SELECT` sobre las columnas a las que hace referencia la expresión del índice — `SELECT` a nivel de columna (por ejemplo, `GRANT SELECT(b)`) es suficiente — porque el `EXPLAIN WHATIF` empírico lee esas columnas.

`DROP HYPOTHETICAL INDEX` y `DROP ALL HYPOTHETICAL INDEXES` no requieren ningún privilegio adicional; solo eliminan registros del almacenamiento local de la sesión.

<div id="see-also">
  ## Véase también
</div>

* [`EXPLAIN WHATIF`](/docs/es/reference/statements/explain#explain-whatif)
* [`system.hypothetical_indexes`](/docs/es/reference/system-tables/hypothetical_indexes)
* [Índices de omisión de datos](/docs/es/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-data_skipping-indexes)
