-
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
Query: Sargability of string literals in combination with non-Unicode columns #4686
Comments
Just came across this with latest vnext rc2 bits. Wondered why my query was suddenly so slow It was because
Taking 2 seconds In SSMS I altered the query to
Taking a few miliseconds. (Note no N on literal '5802685') So it looks like treating all string literals as Unicode will hurt performance in this scenario dramatically Due to CustSuppRef being varchar and indexed |
Is custsuppref mapped AS varchar In Your model? |
Yes. |
Heres the code
|
Clearing up milestone based on the new data. |
BTW the generated sql I posted is just part of 4 queries generated by the code. They all exhibit the same issue. |
Will this fix make it to rc2? |
Custom version of EFCore.Relational, or use FromSQL ? |
Can't EF check what DB type is the string being filtered, and if it's an NVARCHAR use unicode literal and if's VARCHAR is non-unicode literal? And there should be something similar to |
@rowanmiller |
Yes, that is a good description of the fix that we want to implement. Ideally we would recognize all C# relational operators and (as we already saw in @mikes-gh's example) usages of In practice I would expect the solution to do a reasonable effort to recognize those patterns and to leave the rest for some explicit way to specify that a string should be treated as non-Unicode (in EF 6 we had We can try to get something in soon for this but I doubt it will be ready for RC2 (which is rather close). |
@divega @rowanmiller Maybe we could do just the AsNonUnicode part for RC2 so that there is a reasonable workaround? |
@ajcvickers that would be great. |
This is interesting. It seems we can supply a non-Unicode literal or parameter as a predicate against an nvarchar field and index can be used. Sounds like a strong argument for reverting #4667 |
Even if I that is the case I don't think reverting #4667 is the right solution. That change actually fixed a bug. See #4781. @ajcvickers Sounds good to me if that is viable. |
Ah sorry yes sometimes forgot the world is not all on the same alphabet. |
This make interesting reading It appears if we use a windows collation (Latin1_General_CI_AS) on the database, index seek can still be used when comparing an nvarchar predicate to a varchar column.
Of course this is not something to be done lightly but in my case I think it will be a good option as I see no downsides from moving form the SQL collation to the Wndows collation which seems to be the recommended approach anyway now. I will report back. |
OK good news to report
Now runs similar times for N'4802685'' or '4802685'' So basically changing database, table and column collation from SQL_Latin1_General_CP1_CI BTW My sql server installation is set to Latin1_General_CI_AS so any new databases would be this anyway. Changing collation is a bit time consuming but for me its worth it as I now have a more future proof database. I can also still benefit from smaller index size of varchar for large 3mil plus row table and SQL Server now knows how to compare nvarchar to varchar efficiently. Hope this helps someone else. |
#4937 added functionality to infer the Unicode-ness of string literal & parameters for common cases. (when one side of operator is Column/property). |
@smitpatel should we close this issue now? From my understanding of what you checked in, it doesn't seem that the explicit method is compelling anymore. |
There are complex cases which may not be inferred easily which may need method. We can track it in new issue or here only. Either way is fine with me |
General question... How do I know when this fix goes to cidev. |
@mikes-gh - 20401 was successful build number which took this commit in. It should be in cidev packages now. |
filed #4978 for complex cases. Closing this. |
@smitpatel thanks on hols at mo but will report back in this thread in acouple of days |
@smitpatel
Many thanks |
I think I'm coming across something related to this issue... There is a column set up as varchar: Query: The resulting SQL: Since the column is defined as varchar, not sure what is causing the N to be there. Thanks |
@mk9753 could you create a new issue, complete with information about the EF Core version you are using? |
PR #4667 "fixed" issue #4622 by making all string literals Unicode in our SQL generation.
But it has been claimed that SQL Server cannot leverage indexes when comparing a Unicode literal or parameter against a non-Unicode column. For an example, see http://stackoverflow.com/questions/5828621/.
Rather than reopening #4622, I am creating a new issue to discuss the priority of sargability in this scenario on its own.
Whenever we decide to improve this we should verify in which scenarios the claim is valid and then we can avoid creating Unicode literals in those cases.
The text was updated successfully, but these errors were encountered: