【问题标题】:Stored procedure is not using indexes存储过程未使用索引
【发布时间】:2015-06-24 14:03:34
【问题描述】:

这个存储过程是 linq 查询执行的结果:我从 Sql Server Profiler 得到它

exec sp_executesql N'SELECT 
[Limit1].[C2] AS [C1], 
[Limit1].[object] AS [object], 
[Limit1].[C1] AS [C2]
FROM ( SELECT TOP (50) 
    [GroupBy1].[A1] AS [C1], 
    [GroupBy1].[K1] AS [object], 
    1 AS [C2]
    FROM ( SELECT 
        [Extent1].[object] AS [K1], 
        COUNT(1) AS [A1]
        FROM [dbo].[BEM_EVT_FULL] AS [Extent1]
        WHERE [Extent1].[date] > @p__linq__0
        GROUP BY [Extent1].[object]
    )  AS [GroupBy1]
)  AS [Limit1]',N'@p__linq__0 datetime2(7)',@p__linq__0='2015-01-21 00:00:00'

我已经在所有列(对象和日期)上创建了索引。问题是这个查询完全忽略了索引,运行时间超过 3 分钟。

另一方面,我有这个手动运行的查询。

SELECT 
[Limit1].[C2] AS [C1], 
[Limit1].[object] AS [object], 
[Limit1].[C1] AS [C2]
FROM ( SELECT TOP (50) 
    [GroupBy1].[A1] AS [C1], 
    [GroupBy1].[K1] AS [object], 
    1 AS [C2]
    FROM ( SELECT 
        [Extent1].[object] AS [K1], 
        COUNT(1) AS [A1]
        FROM [dbo].[BEM_EVT_FULL] AS [Extent1]
        WHERE [Extent1].[date] > convert(datetime2, '2015-01-21 00:00:00.0000000', 121)
        GROUP BY [Extent1].[object]
    )  AS [GroupBy1]
)  AS [Limit1]

此查询受益于索引并在 1 秒内运行。有谁知道这是为什么?

【问题讨论】:

  • 您是否通过查看计划证明了这一点?是 SQL 分析器还是您的 .NET 代码的时间安排?
  • 参数嗅探?检查计划,看看它是用什么值编译的(左边第一件事的属性)
  • 你怎么知道它忽略了索引?如果只是执行时间,我同意@JamesZ 这可能是参数嗅探的情况。
  • 顺便说一句,this may help
  • @SteveDrake 我已经通过查看 sql server profiler 证明了这一点

标签: sql sql-server tsql stored-procedures indexing


【解决方案1】:

我觉得添加 OPTION(RECOMPILE) 会对您有所帮助。问题是实体框架如何做到这一点。看看这个链接Adding a query hint when calling Table-Valued Function

exec sp_executesql 
    N'SELECT    [Limit1].[C2] AS [C1], 
                [Limit1].[object] AS [object], 
                [Limit1].[C1] AS [C2]
    FROM 
    (
        SELECT TOP (50) [GroupBy1].[A1] AS [C1], 
                        [GroupBy1].[K1] AS [object], 
                        1 AS [C2]
        FROM 
        (
            SELECT 
            [Extent1].[object] AS [K1], 
            COUNT(1) AS [A1]
            FROM [dbo].[BEM_EVT_FULL] AS [Extent1]
            WHERE [Extent1].[date] > @p__linq__0
            GROUP BY [Extent1].[object]
        )  AS [GroupBy1]
    )  AS [Limit1]
    OPTION (RECOMPILE)',

    N'@p__linq__0 datetime2(7)',
    @p__linq__0='2015-01-21 00:00:00'

【讨论】:

  • OP 不控制查询的文本;它是由那个 icky Entity Framework 的东西 that doesn't do a very good job 生成的。
  • 感谢您的提示。我编辑了我的答案,并附上了一个成功完成此任务的人的链接。
  • 呃,太丑了。我想知道您为使 EF 正常运行而必须执行的所有丑陋的变通方法和黑客行为是否值得任何所谓的优势......
  • 我认为我遇到了参数嗅探问题,在 where 语句中传递了 dateTime
  • @Stephan 你确定我们把 OPTION(RECOMPILE) 放在那个语句中吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
相关资源
最近更新 更多