【问题标题】:Alter EF Generated query parameters更改 EF 生成的查询参数
【发布时间】:2020-07-31 09:09:25
【问题描述】:

我正在使用 EF 6.4.4 来查询 SQL 视图。现在视图并不是真正表现最佳,但我无法控制它。

我在字符串/nvarchar 属性上使用 WHERE 语句执行以下代码

_context.ViewObject
   .Where(x => x.Name == nameFilter)
   .ToList();

同样,我在 SMSS 中执行了相同的 SQL 语句

SELECT [Id]
     , [Name]
     , ...
FROM [View]
WHERE [Name] = '<nameFilter>'

我的问题是 EF 变体比直接 SQL 查询慢得多。 在检查 EF 生成的 SQL 查询时,我看到以下内容:

SELECT [Id] 
     , [Name]
     , ...
FROM [View]
WHERE [Name] = @p__linq__0

带有参数@p__linq__0 的类型为 NVARCHAR(4000) NULL

即使我的输入变量不是 NULL 并且最大长度为 6 个字符,这也是如此。 当我使用此参数执行相同的 sql 查询时,SMSS 也很慢。 显然,这是有问题的

所以我想做的是改变 EF 用来生成这个查询的 SQL 查询参数。这是为了确保我的参数在查询中更准确地表示,并且我可以获得与直接在 SMSS 中相同的性能。

有没有办法做到这一点?

【问题讨论】:

  • 你似乎在追逐一条红鲱鱼。如果您也使用参数执行原始查询,并将该参数声明为NVARCHAR(6) NOT NULL,该怎么办?
  • 向我们展示您“使用此参数执行相同的 sql 查询”的代码? [Name] db 列是什么类型,无论是在表中还是在视图中?
  • @CodeCaster 是的,尽管您会注意到最初的断言是在完成 select x from y where z = 'str' 的地方性能很好,而且它不是 Unicode 'str'.. 所以我们真的应该看看首先是 'str'N'str' 的性能(并确保我们正在针对“温暖”数据库执行)

标签: c# sql-server entity-framework


【解决方案1】:

发生了什么:parameter sniffing

在 SSMS 中执行以下操作,您可能会看到相同的性能。

EXECUTE sp_executesql N'SELECT [Id]
         , [Name]
         , ...
    FROM [View]
    WHERE [Name] = @nameFilter'
    ,N'@nameFilter nvarchar(4000)'
    ,@nameFilter = '<namefilter>';

sp_executeSql 被 EF 用于对数据库执行查询,因此,当您编写 .Where(x =&gt; x.Name == nameFilter) 时,这将转换为上述语句。

让你受苦parameter sniffing

您可以通过像here 中描述的那样向查询添加重新编译来解决此问题,但请注意,向所有查询添加重新编译可能会对其他查询产生负面影响。

您可以使用实际执行计划执行以下查询以查看差异:

  • 查询 WHERE Name = @NameFilter
  • 查询 WHERE Name = '&lt;NameFilter&gt;'
  • 查询 WHERE Name = @NameFilter OPTION(RECOMPILE)

如果不是参数嗅探,可能是implicit conversions,但我猜这两种类型都是NVARCHAR,所以这不重要。

99% 的时间是参数嗅探。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多