Reimplement EF.Constant without introducing constant nodes in the funcletizer #33674
Labels
area-perf
area-query
breaking-change
closed-fixed
The issue has been fixed and is/will be included in the release indicated by the issue milestone.
customer-reported
type-enhancement
Milestone
#31552 introduced EF.Constant as a way of telling EF to integrate a captured variable ("parameter") as a constant in the SQL; the implementation was done in the funcletizer, where EF.Constant is stripped away and a constant node is inserted instead. Since the constant node is introduced very early - before our query caching mechanism - different values inside EF.Constant cause cache misses, causing a recompilation of the entire query. This is very heavy for a mechanism that is generally meant to ensure constants in SQL only.
An alternative implementation would ignore EF.Constant in the funcletizer, and have a preprocessing step that records in the QueryCompilationContext that the parameter in question is to actually be constantized. Then, in the 2nd part of the query pipeline - where we have access to parameter values - we'd recognize the parameter based on the QCC record, and replace it with a constant of the actual value. This still means we wouldn't be able to cache the SQL (very much by design), but that's still far better than a full recompilation of the query for different values.
One problematic aspect is that this would need to be implemented for non-relational providers as well (e.g. Cosmos), whereas the funcletizer-based implementation is universal. But that doesn't seem to me to be a blocker (it's very unlikely anyone is using EF.Constant with non-relational providers at this point).
Thanks to @stevendarby for exploring this direction in #25630.
The text was updated successfully, but these errors were encountered: