C# 实体框架Linq查询的问题:在SSMS中立即运行,在EF Linq中运行8-10秒
我在SQL(变量名模糊化)中得到了以下查询,该查询试图获取值(Ch、Wa、Bu、Hi),从而产生最大数量(cnt)的Pi条目C# 实体框架Linq查询的问题:在SSMS中立即运行,在EF Linq中运行8-10秒,c#,sql,sql-server,linq,entity-framework,C#,Sql,Sql Server,Linq,Entity Framework,我在SQL(变量名模糊化)中得到了以下查询,该查询试图获取值(Ch、Wa、Bu、Hi),从而产生最大数量(cnt)的Pi条目 select top 1 Pi.Ch, Pi.Wa, Pi.Bu, Pi.Hi, COUNT(1) as cnt from Product, Si, Pi where Product.Id = Si.ProductId and Si.Id = Pi.SiId and Product.Code = @CodeParameter group by Pi.Ch, Pi.Wa,
select top 1 Pi.Ch, Pi.Wa, Pi.Bu, Pi.Hi, COUNT(1) as cnt
from Product, Si, Pi
where Product.Id = Si.ProductId
and Si.Id = Pi.SiId
and Product.Code = @CodeParameter
group by Pi.Ch, Pi.Wa, Pi.Bu, Pi.Hi
order by cnt desc
它在SQL management studio中的生产数据库上立即运行。我已经在C#LINQ和实体框架中成功地编写了一些代码,但是每种方式的代码运行时间都在8-10秒。一次尝试是以下代码(在不打印的情况下执行,因为一次调用会产生相同的性能结果):
它输出以下SQL语句:
SELECT
[Project1].[C2] AS [C1],
[Project1].[Ch] AS [Ch],
[Project1].[Wa] AS [Wa],
[Project1].[Bu] AS [Bu],
[Project1].[Hi] AS [Hi],
[Project1].[C1] AS [C2]
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [Ch],
[GroupBy1].[K2] AS [Wa],
[GroupBy1].[K3] AS [Bu],
[GroupBy1].[K4] AS [Hi],
1 AS [C2]
FROM ( SELECT
[Extent3].[Ch] AS [K1],
[Extent3].[Wa] AS [K2],
[Extent3].[Bu] AS [K3],
[Extent3].[Hi] AS [K4],
COUNT(1) AS [A1]
FROM [dbo].[Product] AS [Extent1]
INNER JOIN [dbo].[Si] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ProductId]
INNER JOIN [dbo].[Pi] AS [Extent3] ON [Extent2].[Id] = [Extent3].[SiId]
WHERE ([Extent1].[Code] = @p__linq__0) AND (@p__linq__0 IS NOT NULL)
GROUP BY [Extent3].[Ch], [Extent3].[Wa], [Extent3].[Bu], [Extent3].[Hi]
) AS [GroupBy1]
) AS [Project1]
ORDER BY [Project1].[C1] DESC
我还尝试了查询语法,得到了大致相同的结果。我也尝试过直接使用EF进行查询(但时间不长),但无法很快让它工作
在将查询转换为LINQ时,我是否犯了一些错误?有没有一个明显的方法可以改进查询?是否可以使用与SQL语句相同的性能在EF/LINQ中编写查询
======更新======
在SQL分析器中,原始查询的输出完全相同。对于LINQ查询,它与我上面发布的内容非常相似
exec sp_executesql N'SELECT TOP (1)
[Project1].[C2] AS [C1],
[Project1].[Ch] AS [Ch],
[Project1].[Wa] AS [Wa],
[Project1].[Bu] AS [Bu],
[Project1].[Hi] AS [Hi],
[Project1].[C1] AS [C2]
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [Ch],
[GroupBy1].[K2] AS [Wa],
[GroupBy1].[K3] AS [Bu],
[GroupBy1].[K4] AS [Hi],
1 AS [C2]
FROM ( SELECT
[Extent3].[Ch] AS [K1],
[Extent3].[Wa] AS [K2],
[Extent3].[Bu] AS [K3],
[Extent3].[Hi] AS [K4],
COUNT(1) AS [A1]
FROM [dbo].[Product] AS [Extent1]
INNER JOIN [dbo].[Si] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ProductId]
INNER JOIN [dbo].[Pi] AS [Extent3] ON [Extent2].[Id] = [Extent3].[SiId]
WHERE ([Extent1].[Code] = @p__linq__0) AND (@p__linq__0 IS NOT NULL)
GROUP BY [Extent3].[Ch], [Extent3].[Wa], [Extent3].[Bu], [Extent3].[Hi]
) AS [GroupBy1]
) AS [Project1]
ORDER BY [Project1].[C1] DESC',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'109579'
======更新2======
下面是上的查询执行计划的模糊部分。注意,这里讨论的变量在输出中命名为“MagicalCode”,值“109579”和“2449-268-550”与XML输出的最后一行一样有效(C#中的字符串)
<ParameterList>
<ColumnReference
Column="@p__linq__0"
ParameterCompiledValue="N'109579'"
ParameterRuntimeValue="N'2449-268-550'" />
</ParameterList>
显示实际行数的平面图
======更新3======
(隐藏在注释中)我在SSMS中运行了从实体框架生成的EF SQL,它立即运行。因此,我可能正遭受着某种形式的参数嗅探,正如所暗示的。我不知道如何在实体框架的上下文中处理它
======更新4======
已更新,可使用打开
======更新5======
一些变通尝试
- 使用
运行原始查询大约需要4-5秒context.Database.SqlQuery(…)
- 使用
和从EF上下文获得的连接字符串运行原始查询大约需要3秒钟(上下文初始化开销)SqlCommand
- 使用带有硬编码连接字符串的
take运行原始查询大约需要1.5秒。 所以我现在用的是最后一个。我能想到的最后一件事是编写一个存储过程,以接近在SSMS中运行查询的“即时”性能SqlCommand
DBCC FREEPROCCACHE
此外,此线程可能会有所帮助:linq生成的查询没有
TOP1
?无论如何,请发布实际执行计划。@MartinSmithquery.ToString()
在query.First()
之前执行,因此在使用EF(控制台应用程序、win应用程序、web应用程序)时,它不会显示TOP 1
?生成的查询在SSMS中需要多长时间?请同时提供执行计划。Product.code
的数据类型是什么?如果varchar
您将被禁用,这将阻止对代码的搜索。我没有看到证据表明跟踪是问题的一部分。
DBCC FREEPROCCACHE