实体框架生成的SQL运行极其缓慢

时间:2018-07-20 22:52:43

标签: sql sql-server entity-framework

我们最近开始在连接到SQL Server 2012的asp.net/EF5应用程序中遇到性能下降的情况。下面是由SQL Server生成的sql,它需要58秒才能返回单行:

exec sp_executesql N'SELECT TOP (50) 
[Project1].[C1] AS [C1], 
[Project1].[C2] AS [C2], 
[Project1].[Id] AS [Id]
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent2].[FullName] AS [FullName], 
    1 AS [C1], 
    [Extent2].[FullNameWithAddr] + CASE WHEN ([Extent1].[NPI] IS NOT NULL) THEN N''; NPI#: '' + [Extent1].[NPI] ELSE N'''' END + CASE WHEN ([Extent1].[StateLIC] IS NOT NULL) THEN N''; License#: '' + [Extent1].[StateLIC] ELSE N'''' END AS [C2]
    FROM  [dbo].[Provider] AS [Extent1]
    INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
    WHERE (1 = [Extent2].[Active]) AND (([Extent1].[NPI] LIKE @p__linq__0 ESCAPE ''~'') OR ([Extent1].[StateLIC] LIKE @p__linq__1 ESCAPE ''~''))
)  AS [Project1]
ORDER BY [Project1].[FullName] ASC',N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)',@p__linq__0='1043203862%',@p__linq__1='%1043203862%' 

但是,如果我删除了外部投影查询,则新查询(如下所示)将花费不到1秒的时间。请告知我可能采取的任何措施来诊断和解决数据库上的问题;我无法轻松控制EF发出的查询。

exec sp_executesql N' SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent2].[FullName] AS [FullName], 
    1 AS [C1], 
    [Extent2].[FullNameWithAddr] + CASE WHEN ([Extent1].[NPI] IS NOT NULL) THEN N''; NPI#: '' + [Extent1].[NPI] ELSE N'''' END + CASE WHEN ([Extent1].[StateLIC] IS NOT NULL) THEN N''; License#: '' + [Extent1].[StateLIC] ELSE N'''' END AS [C2]
    FROM  [dbo].[Provider] AS [Extent1]
    INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
    WHERE (1 = [Extent2].[Active]) AND (([Extent1].[NPI] LIKE @p__linq__0 ESCAPE ''~'') OR ([Extent1].[StateLIC] LIKE @p__linq__1 ESCAPE ''~''))
',N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)',@p__linq__0='1043203862%',@p__linq__1='%1043203862%' 

编辑: 我确定是导致速度下降的“ TOP”运算符。如果我在下面执行查询,即使使用外部投影查询,它仍然会很快,减去TOP

exec sp_executesql N'SELECT 
[Project1].[C1] AS [C1], 
[Project1].[C2] AS [C2], 
[Project1].[Id] AS [Id]
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent2].[FullName] AS [FullName], 
    1 AS [C1], 
    [Extent2].[FullNameWithAddr] + CASE WHEN ([Extent1].[NPI] IS NOT NULL) THEN N''; NPI#: '' + [Extent1].[NPI] ELSE N'''' END + CASE WHEN ([Extent1].[StateLIC] IS NOT NULL) THEN N''; License#: '' + [Extent1].[StateLIC] ELSE N'''' END AS [C2]
    FROM  [dbo].[Provider] AS [Extent1]
    INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
    WHERE (1 = [Extent2].[Active]) AND (([Extent1].[NPI] LIKE @p__linq__0 ESCAPE ''~'') OR ([Extent1].[StateLIC] LIKE @p__linq__1 ESCAPE ''~''))
)  AS [Project1]
ORDER BY [Project1].[FullName] ASC',N'@p__linq__0 varchar(8000),@p__linq__1 varchar(8000)',@p__linq__0='1043203862%',@p__linq__1='%1043203862%' 

编辑2。 我还确定,如果为顶部计数创建变量,则查询(如下)很快:

declare @p1 int = 50
Select top (@p1) * from 
(
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent2].[FullName] AS [FullName], 
    1 AS [C1], 
    [Extent2].[FullNameWithAddr] + CASE WHEN ([Extent1].[NPI] IS NOT NULL) THEN N'; NPI#: ' + [Extent1].[NPI] ELSE N'' END + CASE WHEN ([Extent1].[StateLIC] IS NOT NULL) THEN N'; License#: ' + [Extent1].[StateLIC] ELSE N'' END AS [C2]
    FROM  [dbo].[Provider] AS [Extent1]
    INNER JOIN [dbo].[Person] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
    WHERE (1 = [Extent2].[Active]) AND (([Extent1].[NPI] LIKE '1043203862%' ESCAPE '~') OR ([Extent1].[StateLIC] LIKE '%1043203862%' ESCAPE '~'))
) a order by a.fullname

0 个答案:

没有答案