【问题标题】:EF Core Parameter Sniffing in SQL ServerSQL Server 中的 EF Core 参数嗅探
【发布时间】:2021-06-23 18:20:38
【问题描述】:

我一直在观看 Brent Ozar 的培训视频(我的 SQL Guru),他谈到参数嗅探并说 EF 会这样做,但对于我的生活,我无法获得一个有效的示例。我期待看到参数,但它只是用相等而不是@p1,@p2 创建这样的 SQL。

SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = 6) AND ([p].[CreationDate] >= '2011-01-01T00:00:00.000')

我通过搭建他的 StackOverflow2013 数据库创建了 DBContext,并在帖子类型上创建了一个外键以获得某种 JOIN。

有谁知道我如何获得使用 EF 进行参数嗅探的示例,因为这每次都会创建一个新的查询计划?

如果我调用存储过程,那么我可以获取参数嗅探。

我的C#代码如下

  var result = ctx.Posts
    .Include(x => x.PostType)
    .Where(x => x.PostTypeId == 6 && x.CreationDate >= new DateTime(2013, 01, 01))
        .Select(x => new {
           Id = x.Id,
           Body = x.Body, 
           Type = x.PostType.Type
         }).ToList();

【问题讨论】:

  • 使用变量,而不是值。
  • Haaaaa 刚试过,是的,就是这样,神奇的是知道它是一个变量而不是一个值

标签: c# sql-server entity-framework-core parameter-sniffing


【解决方案1】:

在我找到答案后不久:)

正如 Gert 在评论中所说,我必须传递一个变量,所以 EF 在那里做了一些魔术。 所以如果我把我的代码改成这个,那么它就会发生:

var myId = 6;

var result = ctx.Posts
    .Include(x => x.PostType)
    .Where(x => x.PostTypeId == myId && x.CreationDate >= new DateTime(2013, 01, 01))
        .Select(x => new {
            Id = x.Id,
            Body = x.Body, 
            Type = x.PostType.Type
        }).ToList();

然后我得到这样的 SQL

exec sp_executesql N'SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = @__myId_0) AND ([p].[CreationDate] >= ''2013-01-01T00:00:00.000'')',N'@__myId_0 int',@__myId_0=6

然后我可以用不同的值执行另一个

exec sp_executesql N'SELECT [p].[Id], [p].[Body], [p0].[Type]
FROM [Posts] AS [p]
INNER JOIN [PostTypes] AS [p0] ON [p].[PostTypeId] = [p0].[Id]
WHERE ([p].[PostTypeId] = @__myId_0) AND ([p].[CreationDate] >= ''2013-01-01T00:00:00.000'')',N'@__myId_0 int',@__myId_0=7

然后我可以在执行计划中看到使用了相同的查询计划,因为第一个查询设置了计划,然后第二个查询使用它并保留估计的 166 行但实际上只有 4 行返回

如果我查看第二个查询属性,我也可以确认这一点,并且可以看到它是用 6 编译的 put 是用 7 运行的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-28
    • 2011-09-01
    • 2010-09-17
    • 1970-01-01
    • 2012-10-10
    • 2019-01-18
    • 2016-05-30
    • 2016-10-07
    相关资源
    最近更新 更多