Un equipo técnico detalla las optimizaciones aplicadas durante cuatro meses para reducir el tiempo de una consulta crítica de ClickHouse desde 85,7 segundos hasta milisegundos, en un caso real de producción. El escenario parte de una tabla de eventos que alimentan la pantalla principal de un panel de analítica, donde se ejecutaban doce consultas en paralelo; cada una recorría hasta 1,96 mil millones de filas y 198,69 GB, con picos de 23,05 GiB de memoria. La tabla usaba el motor ReplacingMergeTree sobre eventos mutables llegados desde Kafka, lo que obligaba a recurrir con frecuencia a FINAL y disparaba los costes de fusión.
Las cuatro grandes palancas de mejora fueron las siguientes. Primero, se cambió la partición mensual por una basada en el hash del identificador de cliente (cliente_customer_id % 36), una decisión contraintuitiva que limita a 36 las partes por inserción, equilibra el tamaño de las particiones y permite deshabilitar costosos pasos de intersección de rangos en FINAL. Segundo, se reordenó la sorting key para colocar event_type al principio, lo que evitó procesar el 16% de filas no utilizadas y rebajó una consulta intermedia de 13,43 a 11,44 segundos. Tercero, se eliminó un JOIN con un segundo FINAL sustituyéndolo por una columna precalculada en la aplicación, lo que redujo la memoria casi 13 veces y el tiempo casi 5 veces. Por último, se precomputaron nueve columnas en una sola de 8 bytes, ahorrando 1,5 GB de lecturas y dejando la consulta final en 1,38 segundos, 49,69 millones de filas y 582,40 MiB de pico.
Los autores subrayan que ninguno de los cambios fue un truco aislado, sino mejoras simples y acumulativas. El texto incluye métricas concretas antes y después de cada intervención y señala las compensaciones, como perder la poda por partición a cambio de ganar paralelismo en FINAL.
