SQL "IN" CLAUSE Performance issue
I have a simple SQL statement:
select * from Employee
where LEFT(REPLACE(EmployeeName,'.',''),4) IN ('ABCE', 'BCDS', 'EDSC', 'XDSD', 'EFSE')
And I'm trying to do this in Linq:
Employees.Where(x => new[] { "ABCE", "BCDS", "EDSC", "XDSD", "EFSE" }.Contains((x.EmployeeName.Replace(".", "").Substring(0, 4))));
but the SQL query he created is ineffective. The EmployeeName is updated every time before comparing against strings, not just once:
SELECT
[Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[EmployeeName] AS [EmployeeName],
[Extent1].[EmployeeTypeID] AS [EmployeeTypeID],
[Extent1].[Active] AS [Active]
FROM [dbo].[Employee] AS [Extent1]
WHERE (N'ABCE' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'BCDS' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'EDsC' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'XDSs' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
OR (N'EFSE' = (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4)))
How do I make the generated SQL look more like the original sql statement? Thanks to
source to share
It's weird, but I rewrote your query and the generated sql statement was
WHERE (SUBSTRING(REPLACE([Extent1].[EmployeeName], N'.', N''), 0 + 1, 4) IN (N'ABCE', N'BCDS', N'EDSC', N'XDSD', N'EFSE')) AND (SUBSTRING(REPLACE([Extent1].[Name], N'.', N'')
I guess it depends on the database and framework used (in my case SQL Server 2008 and EF).
If you are using EF you can force EF to use sql statement
context.Set<Employee>().SqlQuery("select * from Employee where LEFT(REPLACE(EmployeeName,'.',''),4) IN ('ABCE', 'BCDS', 'EDSC', 'XDSD', 'EFSE')");
source to share
I think you cannot (easily at least) control such a detail of the sql statement generation process.
But if you're looking for the best possible query, I would try the operator LIKE
(using a number of conditions in a LINQ query .StartsWith
).
LIKE
can use sql indexes, which is probably not the case with SUBSTRING
and REPLACE
.
source to share