Antes de empezar
nyc_taxi.trips_small_inferred. Créela y cárguela 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.
Descripción general del proceso
- Ejecute tres consultas independientes de carga de trabajo sobre el esquema inferido para establecer una referencia.
- Cree una tabla con tipos de columna más precisos, cargue los mismos datos y vuelva a ejecutar las consultas.
- Cree otra tabla con el mismo esquema optimizado y una clave de ordenación, y vuelva a ejecutar las consultas.
Defina la carga de trabajo de referencia
Estos ajustes ayudan a que las ejecuciones repetidas sean comparables durante las pruebas. Restaure los valores anteriores una vez completadas las mediciones.
system.query_log.
Filtrar por velocidad de trayecto calculada
Agregar viajes en un intervalo de fechas
Filtrar por número de pasajeros
Las tres consultas leyeron aproximadamente 329 millones de filas, una cifra cercana al número de filas de la tabla. Esto permite mejorar dos aspectos distintos de la carga de trabajo: reducir el coste de procesar las columnas seleccionadas y, después, reducir el número de filas seleccionadas cuando los filtros lo permitan.
Optimizar el esquema
Evite columnas Nullable innecesarias
Nullable almacena una máscara de valores nulos además de los valores propiamente dichos. Mantenga Nullable cuando sea relevante distinguir entre un valor nulo y el valor predeterminado del tipo, pero evítelo en las columnas que siempre contengan un valor.
Cuente los valores nulos de las columnas utilizadas en el esquema de ejemplo:
ratecode_id, mta_tax y payment_type contienen valores nulos en este conjunto de datos. El esquema optimizado conserva Nullable en esas columnas y lo elimina de las demás.
Use LowCardinality para valores repetidos
LowCardinality utiliza codificación de diccionario y puede reducir el almacenamiento y el procesamiento de columnas con muchos valores repetidos. Compruebe el número de valores distintos antes de aplicarlo:
LowCardinality, aunque conviene medir su efecto en la carga de trabajo. Unos 10.000 valores distintos constituyen un punto de partida útil para identificar candidatas, no un límite fijo.
Elige tipos de datos más precisos
Int64 o Float64 inferido:
UInt8, aunque passenger_count alcanza el valor máximo de 255. El ejemplo también utiliza Float32 para trip_distance y Decimal32 para los valores monetarios. Todos los valores de este conjunto de datos caben dentro de los rangos de destino, y el ejemplo acepta la menor precisión de coma flotante y la precisión monetaria a nivel de céntimos porque su carga de trabajo compara resultados agregados. Conserve los tipos de origen más amplios cuando se requieran valores exactos de origen. El ejemplo sustituye las columnas DateTime64 inferidas por DateTime en la misma zona horaria UTC, ya que las consultas del ejemplo no requieren precisión de fracciones de segundo.
Estas opciones son específicas de este conjunto de datos. Confirme los requisitos de rango, precisión y nulabilidad de los datos de producción antes de aplicar los mismos cambios.
Aplicar los cambios en el esquema
nyc_taxi.trips_small_inferred por nyc_taxi.trips_small_no_pk y vuelva a ejecutar las tres consultas. El ejemplo original registró los siguientes resultados representativos:
Las consultas siguen leyendo el mismo número de filas, pero el esquema optimizado reduce la cantidad de datos representada por esas filas. Por lo tanto, mejoran la duración de las consultas y el uso máximo de memoria sin modificar la selección de datos.
Compare el tamaño en disco de las dos tablas:
Optimiza la clave de ordenación
MergeTree, la clave de ordenación determina cómo se disponen las filas en disco. ClickHouse crea un índice primario disperso a partir de ese orden para omitir los gránulos que no pueden cumplir los filtros de una consulta. A diferencia de una clave primaria en muchas bases de datos transaccionales, no garantiza la unicidad.
La clave de ordenación debe reflejar los filtros que utilizan las consultas recurrentes más importantes. El orden de las columnas importa: una clave es más eficaz cuando la consulta filtra por un prefijo útil. Las columnas de menor cardinalidad a veces son eficaces como elementos iniciales cuando se filtran con frecuencia, y un componente temporal suele ser útil para cargas de trabajo basadas en el tiempo. Para obtener orientación detallada sobre cómo elegirla, consulta Elegir una clave primaria.
Para este ejemplo, utiliza (passenger_count, pickup_datetime, dropoff_datetime). passenger_count tiene pocos valores distintos y aparece en el filtro por número de pasajeros, mientras que pickup_datetime aparece en la agregación por intervalo de fechas. Aunque pickup_datetime no es la primera columna, ClickHouse puede seguir usando valores de columnas posteriores de la clave para excluir datos cuando la columna inicial no tiene restricciones. Por lo general, filtrar por un prefijo útil de la clave de ordenación permite una poda más eficaz.
Aplicar el cambio de la clave de ordenación
nyc_taxi.trips_small_pk y vuelve a ejecutar las tres consultas.
Compare los resultados
La optimización del esquema reduce el almacenamiento y hace que los valores seleccionados sean menos costosos de procesar. La clave de ordenación aporta la mayor mejora adicional en la agregación por intervalo de fechas, ya que ClickHouse puede omitir los gránulos que quedan fuera del intervalo de fechas. El filtro por número de pasajeros también lee menos filas porque filtra por la primera columna de la clave. El filtro de velocidad calculada sigue leyendo toda la tabla porque se basa en
pickup_datetime, dropoff_datetime y trip_distance, en lugar de en un prefijo útil de la clave de ordenación.
Inspeccione la agregación por intervalo de fechas con EXPLAIN indexes = 1:
En ClickHouse 25.9 y versiones posteriores, estos ajustes garantizan que
EXPLAIN informe de los índices utilizados y de las partes y los gránulos que estos descartan.Aplique el método a su carga de trabajo
- Registre la duración de referencia, las filas y los bytes leídos, y el uso máximo de memoria.
- Compruebe si las columnas seleccionadas usan tipos innecesariamente amplios o permisivos.
- Aplique y mida los cambios de esquema sin modificar la organización de los datos.
- Pruebe una clave de ordenación basada en los filtros utilizados por las consultas recurrentes más importantes.
- Compare los datos seleccionados con
EXPLAIN indexes = 1y, a continuación, vuelva a ejecutar las consultas de referencia en condiciones comparables.