Antes de comenzar
nyc_taxi.trips_small_inferred 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.
ORDER BY (), por lo que su filtro de fecha no puede usar una clave de ordenación para descartar datos durante la lectura. Use el ejemplo para practicar el método de comparación, no como objetivo de rendimiento.
Cómo funciona
- Ejecute la consulta original para establecer las mediciones de referencia.
- Mantenga
GROUP BY, sustituya los cálculos de agregación de la consulta porcounty elimine las operaciones posteriores, como la ordenación y el formato de salida. - Elimine la agrupación y ejecute un
countsin agrupar para aproximar el trabajo correspondiente al escaneo, filtrado y cualquier join.
SELECT a la vez: conserve fuentes de datos y filtros equivalentes, elimine una operación a la vez y verifique el plan de ejecución después de cada cambio.
Estas diferencias son estimaciones de diagnóstico, no mediciones exactas de las etapas de ejecución de ClickHouse. Modificar la consulta puede alterar su plan de ejecución, las columnas leídas y los datos transmitidos entre etapas. Use los resultados para formular una hipótesis. A continuación, valídela con los registros de consultas y
EXPLAIN.Establece una referencia reproducible
- Mantén sin cambios las cláusulas
FROM,JOIN,PREWHEREyWHEREpara que cada comparación use los mismos datos y el mismo intervalo de tiempo. - Ejecuta cada versión de la consulta varias veces con una carga del sistema similar.
- Mantén condiciones de caché coherentes. Ejecuta cada versión de la consulta antes de registrar las mediciones o desactiva las cachés indicadas a continuación. No compares ejecuciones en caché con ejecuciones sin caché.
- Registra una duración representativa, como la mediana de las ejecuciones repetidas tras las ejecuciones de calentamiento, en lugar de basarte en el resultado más rápido o más lento.
- Cambia una variable a la vez para poder asociar una diferencia de rendimiento a un cambio específico.
count de la ejecución C no use un plan de ejecución optimizado que omita el escaneo que pretendes comparar.
Estas sentencias
SET se aplican únicamente a la sesión actual. Ejecute todas las consultas comparativas en esa sesión o aplique la misma configuración en cada ejecución. La configuración de la caché del sistema de archivos no desactiva la caché de páginas del sistema operativo ni todas las cachés de ClickHouse. Cuando termine, cierre la sesión dedicada o restaure cada configuración a su valor anterior.-
Asigne un ID de consulta único a cada ejecución o registre el ID generado por su interfaz de consultas. Por ejemplo, identifique las ejecuciones repetidas como
bottleneck-a-1,bottleneck-a-2ybottleneck-a-3. Conclickhouse-client, pase--query_id your-query-idal ejecutar una consulta. - Ejecute cada consulta comparativa varias veces en las mismas condiciones. Mantenga las ejecuciones de calentamiento separadas de las ejecuciones medidas.
-
Vacíe el registro de consultas antes de buscar consultas completadas recientemente:
Si no puede ejecutar
SYSTEM FLUSH LOGS, espere a que el registro de consultas se vacíe automáticamente y vuelva a intentar la búsqueda. Si el registro nunca aparece, verifique que el registro de consultas esté habilitado, que pueda leersystem.query_logy que esté consultando el nodo que ejecutó la consulta. -
Busque el registro completado correspondiente a cada ID de consulta.
system.query_logregistra eventosQueryStartyQueryFinishpara las consultas completadas. Filtre porQueryFinish, que contiene la duración final, las filas y los bytes leídos, y el pico de memoria: -
Para cada versión de la consulta, use la duración mediana de las ejecuciones medidas. Registre
read_rows,read_bytesy el pico de memoria de la ejecución más cercana a esa mediana para que las mediciones sigan vinculadas a una ejecución real.
Para las consultas distribuidas,
memory_usage en el registro QueryFinish de la consulta iniciadora no representa el pico de todo el clúster. Use initial_query_id para inspeccionar los registros QueryFinish secundarios en los nodos participantes.system.query_log para obtener más información sobre sus campos y configuración.
- Tabla
- CSV
Ejecute consultas cada vez más simples
GROUP BY, omita la ejecución B como se describe a continuación.
1
Ejecución A: Mida la consulta original
Ejecute la consulta completa sin modificar sus filtros, agrupación, expresiones de agregación, ordenación ni salida. Esto establece la duración de referencia, las filas y los bytes leídos, y el uso máximo de memoria.Esta consulta agrupa los viajes por tipo de pago y calcula varios valores agregados:Registre las métricas de la consulta como ejecución A.
2
Ejecución B: Mantenga la agrupación con count
Conserve las cláusulas La ejecución B sigue escaneando y filtrando los datos, realiza los joins necesarios y construye los grupos. Compare su duración con la de la ejecución A para estimar la contribución de las expresiones de agregación originales y del trabajo posterior a la agregación. Compare también
FROM, JOIN, PREWHERE y WHERE, así como las claves de agrupación de la consulta. Sustituya las expresiones de agregación por un count agrupado. Elimine el trabajo posterior a la agregación, incluida la ordenación original y las expresiones de salida.read_bytes, ya que eliminar expresiones de agregación puede eliminar columnas de la lectura.Si la consulta original no contiene GROUP BY, no hay ninguna etapa de agrupación que aislar. Omita la ejecución B y compare la consulta original directamente con la ejecución C.3
Ejecución C: Elimine la agrupación
Elimine La ejecución C proporciona una referencia para las operaciones que conserva su plan, no una medición aislada del escaneo o el filtrado. Compárela con la ejecución B para estimar la contribución de la agrupación. Compare también
GROUP BY y devuelva un único count. Mantenga sin cambios las cláusulas FROM, JOIN, PREWHERE y WHERE para que el trabajo restante sea comparable.read_bytes, ya que eliminar la clave de agrupación puede reducir las columnas leídas. El count devuelto muestra cuántas filas llegan a la agregación tras aplicar los filtros y joins conservados.Antes de interpretar la ejecución C, confirme que su plan de ejecución lee la fuente de datos prevista y aplica los filtros conservados. Una proyección o un recuento basado en metadatos pueden cambiar el trabajo realizado. Para obtener una referencia basada en escaneo, deshabilite la optimización que se muestra en el plan en las tres ejecuciones: use optimize_use_implicit_projections = 0 para una proyección implícita, optimize_use_projections = 0 para una proyección explícita o optimize_trivial_count_query = 0 para un recuento sin filtros obtenido de los metadatos de la tabla.Si la ejecución C sigue siendo lenta, investigue las operaciones que conserva, empezando por el escaneo y el filtrado. Use los registros de consultas y EXPLAIN para validar el cuello de botella sospechado antes de modificar la consulta.Interprete las diferencias
Compare las filas leídas con el resultado de count
read_rows de la ejecución C con el valor devuelto por count. Por ejemplo, si read_rows es de 100 millones y count devuelve 1 millón, ClickHouse examinó aproximadamente 100 filas de origen por cada fila contabilizada. Esto indica que el filtro descartó la mayoría de las filas leídas de la tabla, pero no permite determinar el motivo. Esta proporción está pensada para análisis sencillos de una sola tabla. Para consultas con múltiples fuentes de datos o proyecciones, interprete read_rows mediante el plan de ejecución.
En ClickHouse 25.9 y versiones posteriores, desactive la caché de condiciones de consulta y la aplicación dinámica de índices de omisión de datos antes de inspeccionar el uso de los índices:
EXPLAIN indexes = 1 para ver qué índices utilizó ClickHouse y cuántas partes y gránulos descartó cada índice. Si ClickHouse seleccionó más gránulos de los esperados, compruebe si los filtros se ajustan a la clave de ordenación de la tabla y si la poda de particiones o un índice de omisión de datos podrían descartar más gránulos. Si el plan no incluye una sección Indexes, EXPLAIN no informó de la poda de índices para esa consulta. Por el contrario, es esperable que una consulta analítica sobre toda la tabla lea la mayor parte de ella.
Valide el posible cuello de botella
- Para un cuello de botella de escaneo o filtrado, use
EXPLAIN indexes = 1con la configuración descrita anteriormente para ver qué índices utiliza ClickHouse y cuántas partes y gránulos elimina cada índice. Compruebe si el plan utiliza una proyección implícita en lugar del escaneo previsto. - Para un cuello de botella de agrupación o agregación, inspeccione los eventos de perfil de consulta pertinentes y el uso máximo de memoria.
- Si la ejecución C sigue siendo lenta e incluye joins, compárela con una consulta de diagnóstico que elimine un join cada vez. Una reducción considerable de la duración sugiere que el join eliminado supone una carga significativa. Dado que eliminar un join cambia el significado de la consulta, utilice esta comparación solo para aislar los tiempos e interprete por separado los cambios en el número de filas.
- Para un cuello de botella en otra operación que conserva la ejecución C, inspeccione el plan de ejecución y los eventos de perfil de consulta pertinentes.
EXPLAIN. Aplique un cambio específico y repita las ejecuciones A, B y C en las mismas condiciones. Confirme que el cambio redujo el trabajo previsto y no desplazó el cuello de botella a otro punto.