I wrote a simple EF Core query that makes a select on a table using some where clause to filter data: start date and finish date between the actual date and a field (DescrizioneCommessa) containing a value.
var query = _ctx.Commessas
.Where(x => (x.DataInizioCommessa.HasValue && x.DataInizioCommessa <= DateTime.Now) || !x.DataInizioCommessa.HasValue)
.Where(x => (x.DataFineCommessa.HasValue && x.DataFineCommessa >= DateTime.Now) || !x.DataFineCommessa.HasValue)
.Where(x => x.DescrizioneCommessa.Contains(pattern))
.OrderBy(x => x.DescrizioneCommessa);
To get the raw SQL I just execute the statement:
var sql = facis.ToQueryString();
And the resultant query is:
DECLARE @__pattern_0 nvarchar(50) = N'COMUNE';
SELECT *
FROM [Commessa] AS [c]
WHERE (([c].[DataInizioCommessa] IS NOT NULL AND [c].[DataInizioCommessa] <= GETDATE()) OR [c].[DataInizioCommessa] IS NULL)
AND (([c].[DataFineCommessa] IS NOT NULL AND ([c].[DataFineCommessa] >= GETDATE())) OR [c].[DataFineCommessa] IS NULL)
AND ((@__pattern_0 LIKE N'') OR (CHARINDEX(@__pattern_0, [c].[DescrizioneCommessa]) > 0))
ORDER BY [c].[DescrizioneCommessa]
I notice that it takes very long to perform the query comparing to its hand-written version:
SELECT *
FROM Commessa
WHERE (DescrizioneCommessa LIKE '%COMUNE%')
AND (DataInizioCommessa <= GETDATE() OR DataInizioCommessa IS NULL)
AND (DataFineCommessa >= GETDATE() OR DataFineCommessa IS NULL);
EF Query takes even more than one minute to elaborate, while the normal one is immediate.
I verified that the problem is this part of where clause:
AND ((@__pattern_0 LIKE N'') OR (CHARINDEX(@__pattern_0, [c].[DescrizioneCommessa]) > 0))
If I substitute the above line with:
AND (DescrizioneCommessa LIKE '%COMUNE%')
the problem is resolved, the performance is optimal.
Why this line
.Where(x => x.DescrizioneCommessa.Contains(pattern))
creates this issue?