为什么我的查询在mgmt studio上运行速度快但在特定参数的应用程序中运行缓慢?

时间:2016-05-10 07:40:29

标签: sql-server database entity-framework

我有这个查询(由实体框架4为MSSQL 2008R2生成):

SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[Id] AS [Id], 
[Limit1].[Text] AS [Text], 
[Limit1].[Sender] AS [Sender], 
[Limit1].[Time] AS [Time], 
[Limit1].[Status] AS [Status]
FROM ( SELECT TOP (100) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Sender] AS [Sender], 
    [Extent1].[Time] AS [Time], 
    [Extent1].[Text] AS [Text], 
    [Extent1].[Status] AS [Status], 
    1 AS [C1]
    FROM [dbo].[MyTable] AS [Extent1]
    WHERE (0 = [Extent1].[DeleteStatus]) 
        AND ([Extent1].[OwnerId] = @p__linq__0) 
        AND (1 = [Extent1].[Cateogry])      
        AND ([Extent1].[Id] > @p__linq__1)
)  AS [Limit1]

-- @p__linq__0=123, @p__linq__1 = 1234

除了具有某些特定参数的查询之外,所有查询都会在不到50毫秒内执行(从应用程序,通过EF)。使用这些参数,尽管结果集返回零行,但查询执行时间超过20秒(每次)。当我在管理工作室中运行相同的查询时,它需要0毫秒。该计划(估计和确切)显示如下: Query Plan

SQL-Server探查器显示与此对应的查询:

exec sp_executesql N'SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[Id] AS [Id], 
[Limit1].[Text] AS [Text], 
[Limit1].[Sender] AS [Sender], 
[Limit1].[Time] AS [Time], 
[Limit1].[Status] AS [Status]
FROM ( SELECT TOP (100) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Sender] AS [Sender], 
    [Extent1].[Time] AS [Time], 
    [Extent1].[Text] AS [Text], 
    [Extent1].[Status] AS [Status], 
    1 AS [C1]
    FROM [dbo].[MyTable] AS [Extent1]
    WHERE (0 = [Extent1].[DeleteStatus]) AND ([Extent1].[OwnerId] = @p__linq__0) AND (1 = [Extent1].[Cateogry]) AND ([Extent1].[Id] > @p__linq__1)
)  AS [Limit1]',N'@p__linq__0 bigint,@p__linq__1 bigint',@p__linq__0=123,@p__linq__1=1234

该表格包含以下相关指数:

PK___1(Id) -- Clustered, Column [Id] is bigint
IX____OwnerId_Category(OwnerId,Category,Status) -- Included-Column: DeleteStatus

这可能是什么原因?我该如何解决? 顺便说一下:

  • 表包含50M +行。
  • 统计数据每日更新。
  • 当碎片超过20%时,指数会在3/4天内重建。

从其他帖子中读到,我执行了这些(当然没有理解。我只是在寻找快速修复。):

  • DBCC DROPCLEANBUFFERS
  • DBCC FREEPROCCACHE

但它完全相同。

1 个答案:

答案 0 :(得分:0)

评论中的链接很棒:1)Slow in the Application, Fast in SSMS和2)The Elephant and the Mouse, or, Parameter Sniffing in SQL Server

不是我理解所有这些;但我通过将动态SQL转换为使用索引提示的存储过程来摆脱这种情况。