-
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
!boolean in query should convert to boolean == false rather than boolean != true where possible #23472
Comments
Out of curiosity, what happens if you do |
Can you point to any resources on Deleted <> 1 being harder for indexes than Deleted == 0? |
@roji i dont have documentation just personal investigation on a perf problem we had Query generated by EF Core
Change the Deleted<> 1 to Deleted = 0 ressulted in and the last one is also using a index i was expecting |
@joakimriedel Changing the query to x.Deleted == false is already resolving our issue. The issue is only there when using !x.Deleted |
@davesmits that's interesting. For me running EF Core 5 |
@joakimriedel sorry; we didnt upgrade yet to 5.0. sorry for forgetting to mention we are in 3.1; working on the upgrade but some breaking changes in identity part making it hard |
@davesmits OK one more thing to add for the upgrade to-do list then, if you choose to do Not to hijack this issue but @roji do you know why |
@joakimriedel I'm not sure exactly why this change was done, but we occasionally change/improve the precise SQL constructs which get generated; this shouldn't be a breaking change in any case. However, the different perf characteristics indeed seem important and we should look into it. Thanks for that info @davesmits! |
@roji very minor impact, but still breaking. Indexing a bit column is normally useless unless the data is skewed to either many 0 or many 1. In one of my queries I had a filter with a predicate similar to create index [IX_not_opened] on dbo.Messages (Id) where Opened=0 since there would be pretty few rows with After the upgrade to 5.0 this query didn't use the index anymore, but since it's a rarely used query I didn't notice the performance degradation until this issue posted by @davesmits . Tested my workaround above and the index is now properly used again! Thanks for looking into this! |
Cannot change without #15586 |
@smitpatel I am not sure what you mean convert to int? Is that a internal thing of EF.Core? |
thanks @joakimriedel ; we are now migrating to .net 5 and seeing indeed the problem beeing with with deleted == false . We applied your workaround as well |
Ping @maumar |
In a5f3e26 we unified the translation for We could special case the final step on that translation (SimplifyNegatedBinary), when comparing to bool constant so that it always uses equality, rather than non-equality. This transformation should be safe to do, assuming c# null semantics are being used - in case of negated comparisons we weed out nullability completely in the null semantics |
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
…rather than boolean != true where possible When comparing something to bool constant, which is later negated we now flip the constant true -> false and false -> true, rather than flipping the operation from == to !=
Is there any workaround for EF 5?
The only workaround we know for the moment is going to FromSQL or not to upgrade and wait for EF 6 |
Did you try the workaround I posted in the beginning of this thread? It helped for me. |
@joakimriedel tnx, seams to work with CONVERT(bit, [t].[Computed]) = CAST(0 AS bit) |
Note that the workaround ( e.g. if the index is defined as I'm using latest stable |
Is this going to be corrected with EF Core 6? The workaround is not working for me because of the reason explained above. |
@gparissis This is fixed in 6.0. Please try with EF Core 6.0 RC2. |
Thanks, can't upgrade to a non production version yet, because of compliance restrictions, but I just found a workaround that worked perfect. I used a value conversion and the SQL on the column is generated as [i].[voided] = 0. What I did: The Voided is a bool property that before was translating to Hope it helps. |
I tried but doesn't work |
@gparissis can you share a code repro with 6.0 rc2 which shows the issue still happening? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hi, I have this problem, but I tried very hard but I did not succeed See the pictures below Return of two records But the second image Two points: Tip 2: Question? |
Ask a question
We have in most of our tables a property bool Deleted (not nullable); and you guess in most of our queries we do Where(x => !x.Deleted).
No i notice that the query gets translated to Deleted <> 1 which is for sql different then Deleted == 0 making it for sql harder to use certain indexes. Are there any guidlines towards this?
The text was updated successfully, but these errors were encountered: