Antes de comenzar
nyc_taxi.trips_small_inferred. Para ejecutarlos tal como se muestran, cree y cargue la tabla si aún no lo ha hecho:
Configurar el conjunto de datos de ejemplo
Configurar el conjunto de datos de ejemplo
El archivo Parquet de origen ocupa aproximadamente 5,8 GB. La carga puede tardar varios minutos, según la red y los recursos disponibles.
Elija un enfoque
Si la evidencia no encaja en ninguna de estas categorías, vuelva al plan de consulta en lugar de forzar la consulta a encajar en un enfoque.
Reducir los datos leídos
- Úselo cuando: La consulta lee columnas anchas o que no necesita.
- Cambio: Reduzca el tamaño o el número de columnas que lee la consulta.
- Validar: Compare
read_bytes, el uso de memoria y la duración en las mismas condiciones.
Revisar los tipos de columna
String de uso general para esos valores, y elija el tipo numérico con signo o sin signo más pequeño que represente de forma segura el rango previsto. Para las columnas temporales, use Date o DateTime, salvo que necesite el rango más amplio o la precisión fraccionaria de Date32 o DateTime64.
Use columnas Nullable de forma deliberada
Una columna Nullable almacena una máscara de nulos independiente además de sus valores, que ClickHouse también debe leer y procesar. Úsela cuando sea importante distinguir entre un valor nulo y el valor predeterminado del tipo. Si se garantiza que una columna siempre contiene un valor, un tipo no anulable evita ese trabajo adicional.
Antes de cambiar una columna, compruebe los datos de origen y la ruta de ingestión en lugar de asumir que los datos observados sin valores nulos siempre seguirán sin tenerlos. El ejemplo práctico de optimización muestra cómo identificar columnas que contienen valores nulos y medir el efecto de cambiar el esquema.
Use codificación de diccionario para valores repetidos
LowCardinality utiliza codificación de diccionario y suele ser eficaz para columnas String, como valores de estado, códigos de país u otras dimensiones con muchos menos valores distintos que filas. Unas 10 000 valores distintos constituyen un punto de partida útil para identificar candidatos, no un límite fijo. Evite identificadores y otras columnas con valores mayoritariamente únicos, y compare las mediciones antes y después de cambiar el tipo.
Consulte Selección de tipos de datos para obtener orientación más detallada.
Lea solo las columnas necesarias
SELECT *, especialmente en tablas con muchas columnas o en consultas que devuelven solo un pequeño subconjunto de cada fila.
Use read_bytes de system.query_log para comparar la cantidad de datos leídos antes y después de restringir las columnas seleccionadas. Si read_bytes sigue siendo alto, revise el plan de consulta en busca de expresiones, filtros, joins o consultas anidadas que aún requieran columnas adicionales.
Por ejemplo, si un dashboard solo necesita la hora de recogida, el tipo de pago y el importe total, seleccione esas columnas en lugar de la fila completa:
SELECT *. El número de filas devueltas no cambia, pero read_bytes debe reflejar el menor conjunto de columnas leído.
Alinee la organización de los datos con la consulta
- Úselo cuando: Un filtro selectivo siga leyendo muchas partes o gránulos.
- Cambie: Alinee la organización física con los filtros que utilizan las consultas recurrentes.
- Valide: Compare las partes y los gránulos seleccionados por
EXPLAIN indexes = 1y, a continuación, comprueberead_rows,read_bytesy la duración.
Comience por la clave de ordenación
MergeTree, la clave de ordenación determina cómo se organizan las filas en el disco. De forma predeterminada, también actúa como clave primaria y define el índice primario disperso. A diferencia de una clave primaria en una base de datos OLTP, una clave primaria de ClickHouse no impone unicidad. Su ventaja en cuanto al rendimiento radica en que permite a ClickHouse omitir gránulos que no pueden cumplir los filtros de una consulta.
Priorice las columnas que aparecen con frecuencia en filtros selectivos, incluido su orden dentro de la clave. Agrupar valores relacionados también puede mejorar la compresión. Cuando el orden de agrupación u ordenación de una consulta coincide con la clave, ClickHouse puede usar optimizaciones de orden para GROUP BY u ORDER BY.
Compare las partes y los gránulos seleccionados por EXPLAIN indexes = 1 antes y después de probar una clave de ordenación distinta. Compare también read_rows, read_bytes y la duración en las mismas condiciones. Consulte Elegir una clave primaria para obtener orientación detallada sobre cómo seleccionarla.
La tabla de ejemplo usa ORDER BY (), por lo que el siguiente filtro selectivo por fecha no dispone de una clave de ordenación que pueda descartar gránulos:
En ClickHouse 25.9 y versiones posteriores, estas configuraciones garantizan que
EXPLAIN informe de los índices utilizados y de las partes y los gránulos que descartan.pickup_datetime y, a continuación, ejecute el mismo EXPLAIN sobre ella. La sección de clave primaria del plan debería mostrar menos gránulos seleccionados antes de usar mediciones de duración o memoria para evaluar el cambio global.
Evalúe opciones adicionales de indexación y organización de datos
EXPLAIN indexes = 1 para confirmar que la consulta realmente descarta particiones.
Agregue un índice de omisión de datos para un filtro localizado
Un índice de omisión de datos almacena metadatos que permiten a ClickHouse evitar leer bloques que no pueden satisfacer un filtro. Resulta más útil cuando la clave de ordenación no admite un filtro importante y los valores coincidentes están suficientemente localizados dentro de los bloques.
Por ejemplo, un índice de filtro Bloom puede ayudar en búsquedas por igualdad cuando la mayoría de los bloques no contiene el valor buscado. Use índices de omisión después de revisar los tipos de datos y la clave de ordenación. Un índice que rara vez excluye un bloque añade sobrecarga de almacenamiento y evaluación sin reducir mucho el trabajo. Pruebe el tipo de índice y la granularidad con datos representativos y, a continuación, use EXPLAIN indexes = 1 para comparar los gránulos seleccionados y comprobar read_rows, read_bytes y la duración.
Use proyecciones de forma selectiva
Las proyecciones almacenan organizaciones de datos alternativas junto con una tabla. Pueden proporcionar otra clave de ordenación o un resultado precalculado, y ClickHouse puede seleccionar una proyección aplicable sin que la consulta tenga que hacer referencia a ella directamente.
Por ejemplo, una proyección ordenada por payment_type puede admitir un filtro recurrente que la ordenación de la tabla base no admite. Use un número reducido de proyecciones para patrones de acceso importantes que la ordenación base no pueda atender eficientemente.
Las proyecciones almacenan datos adicionales de índices o columnas y añaden trabajo durante la inserción y la fusión; una proyección de columnas completas duplica las columnas que almacena. El uso intensivo de proyecciones también puede aumentar el trabajo necesario para elegir una proyección óptima en tiempo de consulta. Para implementaciones grandes con muchos patrones de acceso distintos, suele ser más fácil operar con menos proyecciones o con tablas independientes diseñadas para un propósito específico. Consulte Vistas materializadas frente a proyecciones al elegir entre estos mecanismos.
Agregue una ordenación alternativa para las consultas que filtran por tipo de pago y hora de recogida, sin dejar de consultar la tabla de origen:
EXPLAIN projections = 1 para confirmar si ClickHouse selecciona la proyección y lee menos filas o bytes. Mida también la sobrecarga de inserción y almacenamiento antes de aplicar este patrón de forma generalizada.
Precalcular trabajo repetible
- Úselo cuando: Las mismas transformaciones o agregaciones consumen repetidamente la mayor parte del tiempo de consulta.
- Cambio: Traslade los cálculos repetibles a la ingestión, una actualización programada o una organización de datos diseñada específicamente para ese fin.
- Validar: Confirme que la consulta lee un resultado más pequeño y realiza menos cálculos durante su ejecución, mientras que la carga de ingestión o actualización sigue siendo aceptable.
Cada sección incluye una implementación básica, la principal contrapartida operativa y una forma de validar el resultado.
Vista materializada incremental
sum(trip_count), agrupada por pickup_date, para combinar durante la consulta las filas pendientes de una fusión en segundo plano. La vista procesa únicamente las nuevas inserciones, por lo que debes cargar por separado los datos de origen existentes. Valida el cambio comparando la duración y las filas leídas con la agregación original; después, confirma que el trabajo de inserción adicional sea aceptable.
Vista materializada actualizable
system.view_refreshes para confirmar que la duración, el estado y la frecuencia de actualización se adapten a la carga de trabajo.
Tabla diseñada para un fin específico
Nullable de esas dos columnas de destino. Confirme que este enfoque se ajuste a los requisitos de datos de la carga de trabajo. El dashboard debe consultar esta tabla explícitamente, y la canalización de ingestión debe mantenerla actualizada. Valide el cambio comparando las filas y los bytes leídos, el uso de memoria y la duración con la consulta de la tabla de origen. Tenga en cuenta el almacenamiento adicional y el mantenimiento de la canalización al tomar la decisión.