You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix: Optimizer Missing Final Step - Combine Remaining WHERE Clauses (#732)
* fix: Optimize queries without joins by combining multiple WHERE clauses
Addresses issue #445 - performance slowdown when using multiple .where() calls.
## Problem
When using multiple .where() calls on a query without joins:
```javascript
query.from({ item: collection })
.where(({ item }) => eq(item.gridId, gridId))
.where(({ item }) => eq(item.rowId, rowId))
.where(({ item }) => eq(item.side, side))
```
The optimizer was skipping these queries entirely, leaving multiple WHERE
clauses in an array. During query compilation, each WHERE clause was applied
as a separate filter() operation in the D2 pipeline, causing a 40%+ performance
degradation compared to using a single WHERE clause with AND.
## Solution
Modified the optimizer to combine multiple WHERE clauses into a single AND
expression for queries without joins. This ensures only one filter operator is
added to the pipeline, improving performance while maintaining correct semantics.
The optimizer now:
1. Detects queries without joins that have multiple WHERE clauses
2. Combines them using the AND function
3. Reduces pipeline complexity from N filters to 1 filter
## Testing
- Updated existing optimizer tests to reflect the new behavior
- All 42 optimizer tests pass
- Added new test case for combining multiple WHERE clauses without joins
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* docs: Add changeset and investigation report for issue #445
- Added changeset for the WHERE clause optimization fix
- Documented root cause analysis and solution details
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* fix: Complete optimizer fix - combine remaining WHERE clauses after pushdown
This completes the fix for issue #445 by implementing the missing "step 3" of
the optimizer process.
## Problem (Broader than Initially Identified)
The optimizer was missing the final step of combining remaining WHERE clauses
after optimization. This affected:
1. Queries WITHOUT joins: All optimization was skipped, leaving multiple
WHERE clauses as separate array elements
2. Queries WITH joins: After predicate pushdown, remaining WHERE clauses
(multi-source + unpushable single-source) were left as separate elements
Both cases resulted in multiple filter() operations in the pipeline instead
of a single combined filter, causing 40%+ performance degradation.
## Solution
Implemented "step 3" (combine remaining WHERE clauses) in two places:
1. **applySingleLevelOptimization**: For queries without joins, combine
multiple WHERE clauses before returning
2. **applyOptimizations**: After predicate pushdown for queries with joins,
combine all remaining WHERE clauses (multi-source + unpushable)
## Testing
- Added test: "should combine multiple remaining WHERE clauses after optimization"
- All 43 optimizer tests pass
- Updated investigation report with complete analysis
- Updated changeset to reflect the complete fix
Thanks to colleague feedback for catching that step 3 was missing!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* style: Run prettier on markdown files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* docs: Add PR body update for issue #445 fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* docs: Remove specific 40% performance claim
The original issue compared TanStack db with Redux, not the bug itself.
Changed to more general language about performance degradation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* docs: Remove temporary investigation and PR body files
These were used for context during development but aren't needed in the repo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* fix: Flatten nested AND expressions when combining WHERE clauses
Addresses reviewer feedback - when combining remaining WHERE clauses after
predicate pushdown, flatten any nested AND expressions to avoid creating
and(and(...), ...) structures.
Changes:
- Use flatMap(splitAndClausesRecursive) before combineWithAnd to flatten
- Added test for nested AND flattening
- Added test verifying functional WHERE clauses remain separate
All 45 optimizer tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* style: Remove issue reference from code comment
As requested by @samwillis - issue references in code comments can become
stale. The comment is self-explanatory without the reference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
---------
Co-authored-by: Claude <[email protected]>
Fixed performance issue where using multiple `.where()` calls created multiple filter operators in the query pipeline. The optimizer now implements the missing final step (step 3) of combining remaining WHERE clauses into a single AND expression. This applies to both queries with and without joins:
6
+
7
+
- Queries without joins: Multiple WHERE clauses are now combined before compilation
8
+
- Queries with joins: Remaining WHERE clauses after predicate pushdown are combined
9
+
10
+
This reduces filter operators from N to 1, making chained `.where()` calls perform identically to using a single `.where()` with `and()`.
0 commit comments