The "DB::Exception: Too many query plan optimizations" error in ClickHouse occurs when the query optimizer exceeds its maximum number of optimization iterations. The TOO_MANY_QUERY_PLAN_OPTIMIZATIONS error code indicates that the optimizer has been unable to converge on a final query plan within the allowed number of passes, typically due to the query being exceptionally complex.
Impact
The query is rejected during the optimization phase, before any data is actually read. This primarily affects very complex queries with numerous joins, subqueries, or expressions that cause the optimizer to iterate excessively. Normal queries rarely encounter this error, so its occurrence usually signals that the query structure needs attention.
Common Causes
- Extremely complex queries with many JOINs, subqueries, and nested expressions
- Queries where optimizer rules interact in ways that cause repeated transformations without convergence
- Views that expand into large query plans when inlined
- Programmatically generated SQL with redundant or conflicting optimization opportunities
- Edge cases in the optimizer that cause it to loop between equivalent plan transformations
Troubleshooting and Resolution Steps
Check the optimization limit setting:
SELECT name, value FROM system.settings WHERE name = 'max_query_plan_optimizations';Increase the limit to allow more optimization passes:
SET max_query_plan_optimizations = 100000; SELECT ...;Simplify the query. Break it into smaller pieces using temporary tables:
-- Instead of one massive query with 10 JOINs: CREATE TEMPORARY TABLE step1 AS SELECT ... FROM t1 JOIN t2 ON ... JOIN t3 ON ...; CREATE TEMPORARY TABLE step2 AS SELECT ... FROM step1 JOIN t4 ON ... JOIN t5 ON ...; SELECT ... FROM step2 JOIN t6 ON ...;Disable specific optimizations to reduce the number of passes:
SET optimize_move_to_prewhere = 0; SET optimize_substitute_columns = 0; SET optimize_count_from_count_distinct = 0; SELECT ...;Try disabling optimizations one at a time to identify which one causes the excessive iterations.
Examine the query plan to understand its complexity:
EXPLAIN PLAN SELECT ...; EXPLAIN PIPELINE SELECT ...;Flatten view references. If the query uses views that contain complex logic, consider inlining and simplifying the view definitions manually.
Update ClickHouse. Optimizer convergence issues are sometimes bugs that get fixed in newer versions. Check the changelog for relevant improvements.
Best Practices
- Keep individual queries reasonably simple; split complex analytics into multiple staged queries.
- Avoid creating views that layer on top of other complex views, as the expanded plan can be enormous.
- When generating SQL programmatically, minimize redundant expressions that the optimizer must process.
- Test complex queries in development environments where you can observe optimizer behavior.
- If you must increase the optimization limit, do so at the session level for specific queries rather than globally.
Frequently Asked Questions
Q: What is the default optimization iteration limit?
A: The default value depends on the ClickHouse version. It is typically set high enough that standard queries never reach it. Check your version's documentation or query system.settings for the exact value.
Q: Does increasing the limit always fix the problem?
A: Not necessarily. If the optimizer is genuinely looping between equivalent transformations, increasing the limit may just delay the error. Simplifying the query is often a more reliable fix.
Q: Can this error indicate a bug in ClickHouse?
A: Yes. If a reasonably simple query triggers this error, it may indicate an optimizer bug where rules conflict and cause infinite loops. Consider reporting it on the ClickHouse GitHub with a reproducible query example.
Q: Does disabling optimizations hurt query performance?
A: It can. Each optimization exists to improve execution speed. However, the performance impact depends on the specific optimization and your query. Disabling one optimization to get the query to run at all is often preferable to the query not running at all. You can re-enable optimizations selectively to find the right balance.