Filtros sargables: el rango sobre la columna cruda
IntermedioUn filtro es sargable (del inglés Search ARGument ABLE) cuando compara la columna tal como está guardada contra un valor, por ejemplo created_at >= '2025-08-01'. Así el motor puede usar un índice sobre esa columna para ir directo al rango. Si aplicas una función a la columna (date_trunc, extract, lower), el motor tiene que calcularla fila por fila.
Sintaxis
WHERE columna_fecha >= 'inicio'
AND columna_fecha < 'fin_exclusivo'Ejemplo
SELECT
count(*) FILTER (
WHERE o.created_at >= '2025-08-01'
AND o.created_at < '2025-09-01'
) AS con_rango,
count(*) FILTER (
WHERE date_trunc('month', o.created_at) = '2025-08-01'
) AS con_date_trunc,
count(*) FILTER (
WHERE extract(year FROM o.created_at) = 2025
AND extract(month FROM o.created_at) = 8
) AS con_extract
FROM orders AS o
WHERE o.currency = 'CLP';Resultado
| con_rango | con_date_trunc | con_extract |
|---|---|---|
| 104 | 104 | 104 |
Cómo leerlo
Las tres formas encuentran los mismos 104 pedidos en pesos chilenos de agosto de 2025: el resultado no cambia. Lo que cambia es el trabajo. Con un índice sobre created_at, el rango le permite al motor saltar al 1 de agosto y leer hasta el 31. Las otras dos versiones obligan a calcular date_trunc o extract en cada fila de la tabla y comparar después.
Error común
Así no
SELECT id, created_at
FROM orders
WHERE date_trunc('month', created_at) = '2025-08-01'
AND currency = 'CLP';Filtrar con una función aplicada a la columna. La consulta es correcta, pero un índice sobre created_at no sirve para ella, porque el índice está ordenado por el valor de la columna y no por el resultado de date_trunc. En una tabla chica no se nota; en una de cientos de millones de filas es la diferencia entre leer un rango y leerla completa.
En otros motores: PostgreSQL, Oracle, MySQL, SQL Server, BigQuery, Snowflake
PostgreSQLOracleMySQLSQL Server
Existen índices sobre expresiones: en PostgreSQL, índices de expresión; en Oracle, function-based indexes; en MySQL 8.0.13 o posterior, partes de clave funcionales; en SQL Server, índices sobre columnas calculadas. Son una solución de ingeniería; como analista, reescribir el filtro como rango suele ser lo más simple.
BigQuerySnowflake
No usan índices como los de una base transaccional, pero la idea se aplica igual: un filtro por rango sobre la columna de partición o de fecha, sin funciones encima, es lo que mejor le permite al motor descartar bloques de datos sin leerlos.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.