【发布时间】:2021-08-09 05:14:27
【问题描述】:
我编写了一个简单的 EF Core 查询,它使用一些 where 子句对表进行选择以过滤数据:开始日期和结束日期介于实际日期和包含值的字段 (DescrizioneCommessa) 之间。
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);
要获取原始 SQL,我只需执行以下语句:
var sql = facis.ToQueryString();
结果查询是:
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]
我注意到与手写版本相比,执行查询需要很长时间:
SELECT *
FROM Commessa
WHERE (DescrizioneCommessa LIKE '%COMUNE%')
AND (DataInizioCommessa <= GETDATE() OR DataInizioCommessa IS NULL)
AND (DataFineCommessa >= GETDATE() OR DataFineCommessa IS NULL);
EF 查询甚至需要一分钟以上的时间来详细说明,而正常的查询是立即的。
我确认问题出在 where 子句的这一部分:
AND ((@__pattern_0 LIKE N'') OR (CHARINDEX(@__pattern_0, [c].[DescrizioneCommessa]) > 0))
如果我将上面的行替换为:
AND (DescrizioneCommessa LIKE '%COMUNE%')
问题解决了,性能最优。
为什么是这条线
.Where(x => x.DescrizioneCommessa.Contains(pattern))
造成这个问题?
【问题讨论】:
-
ef 核心 5 还是 ef6?请不要同时标记。
标签: sql sql-server entity-framework-core ef-core-5.0