-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible optimization of split querys with window functions in included entities #34362
Comments
@georg-jung EF doesn't currently perform such optimizations, of implicitly lowering the external predicate into the subquery; we generally don't go too far in to the domain of "taking the place of the planner" (i.e. transform the query so that it makes the database planner produce better plans) - though this is something we could consider for the future, as a more advanced form of optimization category. I'd still need to fully think about this - the danger with such optimizations is that they concievably might regress performance for other query shapes (or other databases), so one must be very careful. Putting on the backlog to consider for future work - thanks for the suggestion. |
Note also #12776 (comment), which is an alternative implementation of split query which wouldn't embed the principal query in the dependent one, that could mitigate this particular case (though the general optimization may still may sense in other situations). |
Thanks for the explanation and for pointing to #12776. I think that it would indeed help in this case. Probably this doesn't change too much about the dangers and complexities you mentioned, but just as a side note: At least in this particular case lowering the external predicate isn't the only option that helps. Lifting and repeating it in the main query would go quite far too:
Seems like lifting and lowering the same predicate in the same query is escpecially hard for the planner. Maybe lifting and repeating is safer to do as an optimization from the EF perspective. |
Some combinations of
AsSplitQuery()
andFirstOrDefault()
withTake()
inInclude()
produce querys that execute slowly on SQLite and Postgres (I didn't test others). I'm unsure if EF Core does the kind of optimization I think of in general, but it seems easy to handcraft SQL that is semantically equalivalent and executes much faster.Repro
Output with SQLite
Possible optimization
It seems to me that the query planner of SQLite and Postgres alike is not able to use an index on BlogReviewers.BlogId effectively for queries like this. If we add a predicate to the subquery manually that filters for the same id as is already done in the main query, the index will be used and the query executes much faster. Is this something general enough so that it can be done in EF or is this an optimization that is to specific to my circumstances?
Workaround
Doing e.g.
(await q.ToListAsync()).FirstOrDefault()
seems counter intuitive first but results in a better query plan and probably the same amount of data on the wire as with EF-sideFirstOrDefaultAsync()
.The text was updated successfully, but these errors were encountered: