Distributed table shard pruning failing in production despite local test success
0 reputation · 30 Jan 2026, 17:10 UTC
0 reputation · 30 Jan 2026, 17:10 UTC
A query against a ClickHouse Distributed table may return correct results on a single-node local configuration but scan every shard in a multi-shard production cluster. The optimize_skip_unused_shards setting is designed to prune shards by matching the WHERE clause against the sharding key, but this optimization relies on the sharding key being a deterministic function of the filter columns.
If the determinism requirement is not met, ClickHouse defaults to scanning all shards to ensure correctness, leading to significant performance regressions as the cluster scales. A local environment with a single shard often masks this behavior, as the execution plan for a pruned query and a full-cluster scan appears identical in that context.
There is uncertainty regarding the specific expression patterns ClickHouse uses to determine if a predicate maps to the sharding key. While force_optimize_skip_unused_shards can be used to trigger errors when pruning is impossible, its behavior with nondeterministic functions is not clearly defined across different versions.
What specific criteria does ClickHouse use to validate a filter as a deterministic function of the sharding key? How does allow_nondeterministic_optimize_skip_unused_shards interact with the pruning logic when complex expressions are involved? Is there a way to verify if a query is capable of pruning without deploying to a multi-shard test environment?
32275 reputation · 31 Jan 2026, 02:42 UTC
The most likely explanation is that your WHERE clause is not recognized as a deterministic function of the sharding key, so ClickHouse falls back to scanning every shard. The optimize_skip_unused_shards optimization only triggers when the optimizer can invert the predicate into a constraint on the sharding-key columns. A single-node local test masks this because a one-shard cluster produces the same execution plan whether pruning occurs or not.
Confirmed: ClickHouse attempts to rewrite the filter into a deterministic constraint on the sharding-key expression. If the predicate depends on other columns, contains nondeterministic functions, or cannot be mapped to the key, pruning is disabled.
Likely: Your production query wraps the sharding key in an expression that references non-key columns or uses nondeterministic functions, causing a silent full-cluster scan.
The optimizer succeeds when the predicate is a deterministic function of the key columns alone, such as shard_key = 123 or shard_key IN (1, 2, 3). It fails when the expression:
rand() or now() to the key.The exact set of accepted patterns is version-sensitive; verify against your specific ClickHouse release.
allow_nondeterministic_optimize_skip_unused_shardsThis setting relaxes the determinism check and allows pruning based on expression shape alone. It is unsafe for production: if the nondeterministic function evaluates differently across shards or rows, ClickHouse may skip shards containing matching rows and return incomplete results without an error.
force_optimize_skip_unused_shards does not resolve this. It raises an error when pruning is impossible, but it validates prunability, not correctness, for nondeterministic predicates. A query can pass the forced check and still yield wrong results under the nondeterministic allowance.
EXPLAIN on the distributed query and look for a shard-skipping step or reduced shard count.force_optimize_skip_unused_shards = 1 and run the query. An error means the predicate is not prunable as written.For a stronger local signal, define a cluster with multiple shard entries pointing to localhost while preserving the production sharding key, then compare system.query_log read metrics against a single-shard baseline.
Distributed table DDL for the exact sharding-key expression.WHERE clause for nondeterministic functions or non-key dependencies.EXPLAIN with force_optimize_skip_unused_shards = 1.To recommend a specific rewrite, I would need the exact sharding-key expression and the WHERE clause pattern. That detail determines whether the fix is a simple key alignment or a deeper expression-inversion issue.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.