Changelog 2026

- Allow any deterministic expression in Primary Key to be used for data skipping (e.g. `ORDER BY cityHash64(user_id)`/ `ORDER BY length(user_id)`). For deterministic expressions, ClickHouse can apply the expression to query constants and use the result in the primary key index for predicates like `=`, `IN`, and `has`. If the expression is also injective (e.g. `ORDER BY hex(p)` or `ORDER BY reverse(tuple(reverse(p), hex(p)))`), we can effectively use the index for the negated forms: `!=`, `NOT IN`, and `NOT has`. Closes [#10685](https://github.com/ClickHouse/ClickHouse/issues/10685). Closes [#82161](https://github.com/ClickHouse/ClickHouse/issues/82161). [#92952](https://github.com/ClickHouse/ClickHouse/pull/92952) ([Nihal Z. Miaji](https://github.com/nihalzp)).
- Improved storage format of statistics. All statistics are now stored in a single file. [#93414](https://github.com/ClickHouse/ClickHouse/pull/93414) ([Anton Popov](https://github.com/CurtizJ)).
- Allow parallelized read for remote table engines/functions in the filesystem cache. [#71781](https://github.com/ClickHouse/ClickHouse/pull/71781) ([Kseniia Sumarokova](https://github.com/kssenii)).
- Allow using userspace page cache with local files and object storage table functions. [#77874](https://github.com/ClickHouse/ClickHouse/pull/77874) ([Michael Kolupaev](https://github.com/al13n321)).
- Avoid unnecessary memcpy in userspace page cache. [#77884](https://github.com/ClickHouse/ClickHouse/pull/77884) ([Michael Kolupaev](https://github.com/al13n321)).
- The default for `concurrent_threads_scheduler` is now `max_min_fair` instead of `fair_round_robin`. This improves fairness under high load by prioritizing queries with fewer allocated slots, so short-running queries aren't penalized by long-running ones. [#95300](https://github.com/ClickHouse/ClickHouse/pull/95300) ([Sergei Trifonov](https://github.com/serxa)).
- If a `FINAL` query used primary key condition for filtering followed by skip indexes for other conditions, the `PrimaryKeyExpand` processing step will now only check the initial shortlisted primary key ranges for intersection. [#94903](https://github.com/ClickHouse/ClickHouse/pull/94903) ([Shankar Iyer](https://github.com/shankar-iyer)).
- When using parallel replicas with table functions like `s3(...)`, queries with a single subquery wrapping the table function are now automatically parallelized across replicas, whereas previously only direct table function references were parallelized. Closes [#92264](https://github.com/ClickHouse/ClickHouse/issues/92264). [#96332](https://github.com/ClickHouse/ClickHouse/pull/96332) ([phulv94](https://github.com/phulv94)).
- Enable splitting data and system files in cache into separate segments. [#87834](https://github.com/ClickHouse/ClickHouse/pull/87834) ([MikhailBurdukov](https://github.com/MikhailBurdukov)).
- Speed up some hash join operations by implementing dynamic dispatch for `ColumnVector::replicate`. [#79573](https://github.com/ClickHouse/ClickHouse/pull/79573) ([Raúl Marín](https://github.com/Algunenano)).
- Performance improvement for parallel hash join in cases of complex predicates. Previously, we were processing non-joined rows in one thread, which is suboptimal the idea of the optimization is to parallelize the processing of the non-joined rows across multiple threads. Can be toggled by the `parallel_non_joined_rows_processing` setting. Enabled by default. [#92068](https://github.com/ClickHouse/ClickHouse/pull/92068) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
- Slightly optimize parsing of JSON type. [#93614](https://github.com/ClickHouse/ClickHouse/pull/93614) ([Pavel Kruglov](https://github.com/Avogar)).
- Improve memory footprint of AST. Optimization makes sense as fields are not used when highlighting is not used and there is no VALUES parsing. [#93974](https://github.com/ClickHouse/ClickHouse/pull/93974) ([Ilya Yatsishin](https://github.com/qoega)).
- Optimize memory consumption of named Tuple AST objects. Place column names as strings in tuple object instead of having them in generic AST literal nodes. [#94704](https://github.com/ClickHouse/ClickHouse/pull/94704) ([Ilya Yatsishin](https://github.com/qoega)).
- Devirtualization is improved with additional linker options. [#94737](https://github.com/ClickHouse/ClickHouse/pull/94737) ([Nikita Taranov](https://github.com/nickitat)).
- Improve clone replica performance for ReplicatedMergeTree tables with many parts by batching ZooKeeper requests. [#94847](https://github.com/ClickHouse/ClickHouse/pull/94847) ([c-end](https://github.com/c-end)).
- When read step already has PREWHERE filters a new filter couldn't be added. This change postpones PREWHERE optimization until after JOIN runtime filter optimization so that runtime filters can be also pushed to PREWHERE. [#95838](https://github.com/ClickHouse/ClickHouse/pull/95838) ([Alexander Gololobov](https://github.com/davenger)).
- Speedup `T64` codec compression by using dynamic dispatch on x86. [#95881](https://github.com/ClickHouse/ClickHouse/pull/95881) ([Raúl Marín](https://github.com/Algunenano)).
- Speed up `uniq` over numeric types by batching inserts when possible (not null, not -If, no GROUP BY, no IPv6 or String). [#95904](https://github.com/ClickHouse/ClickHouse/pull/95904) ([Raúl Marín](https://github.com/Algunenano)).
- Low-level optimizations for Keeper: `ZooKeeper::observeOperations` has been found to account for >20% of the ZooKeeper receive thread CPU consumption. This change addresses that by: 1. For `AggregatedZooKeeperLog::stats`, use `CityHash64` instead of `SipHash` which is >10x faster. 2. For `Coordination::ErrorCounter`, use `std::array<std::atomic<UInt32>, N>` instead of `std::unordered_map` and `std::mutex`. [#95962](https://github.com/ClickHouse/ClickHouse/pull/95962) ([Miсhael Stetsyuk](https://github.com/mstetsyuk)).
- Remove 64-byte alignment for ProfileEvents::Counter to save memory. [#96097](https://github.com/ClickHouse/ClickHouse/pull/96097) ([Azat Khuzhin](https://github.com/azat)).
- Memory optimization: trim size of `CachedOnDiskReadBufferFromFile` structure 50x. [#96098](https://github.com/ClickHouse/ClickHouse/pull/96098) ([Azat Khuzhin](https://github.com/azat)).
- Don't copy old data on hash table resizing if it's empty. [#96180](https://github.com/ClickHouse/ClickHouse/pull/96180) ([Raúl Marín](https://github.com/Algunenano)).
- Support JOIN runtime filters for `RIGHT OUTER` JOINs. [#96183](https://github.com/ClickHouse/ClickHouse/pull/96183) ([Hechem Selmi](https://github.com/m-selmi)).
- The optimization `enable_join_runtime_filters` is now the default. [#89314](https://github.com/ClickHouse/ClickHouse/pull/89314) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
- Previously, text index direct read optimization was applied only when all parts had a materialized text index. This PR adds partial support: if some parts have a materialized text index, those parts will use it, while parts without a materialized text index will fall back to executing the original filter expression. [#96411](https://github.com/ClickHouse/ClickHouse/pull/96411) ([Anton Popov](https://github.com/CurtizJ)).
- Added `minmax` secondary indexes on time columns and `bloom_filter` indexes on `query_id`/`initial_query_id` columns to system log tables for faster filtering. [#96712](https://github.com/ClickHouse/ClickHouse/pull/96712) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
- Lazy materialization optimization is now applied to all branches of a `UNION ALL` query, not just the first one. Queries that combine multiple sorted and limited reads from different `MergeTree` tables via `UNION ALL` will now benefit from deferred column reading on every branch, reducing I/O. [#96832](https://github.com/ClickHouse/ClickHouse/pull/96832) ([Federico Ginosa](https://github.com/menxit)).
- Optimize minmax skip index computation during INSERT by removing an unnecessary data copy and enabling vectorized min/max calculation for numeric columns. [#97392](https://github.com/ClickHouse/ClickHouse/pull/97392) ([Raúl Marín](https://github.com/Algunenano)).