【问题标题】:Getting record counts with Entity Framework results in high number of reads使用 Entity Framework 获取记录计数会导致大量读取
【发布时间】:2021-09-02 20:17:21
【问题描述】:

SQL Server 2016,.NET 4.6.2 上的实体框架 6.4

鉴于这两个表:

  • ParentTable (int masterId, int id)
  • ChildTable (int id, bit isActive)

ParentTableid 列上的 ChildTable 之间存在一对多关系。

我想计算有多少“活动”子行,masterId 为 1。在 T-SQL 中足够简单

select count(1) 
from parentTable 
join childTable on parentTable.id = childTable.id
where masterId = 1 and isActive = 0

现在我想在实体框架中这样做。同样,语法很简单:

 var activeCount= db.childTable.Count(d => d.parentTable.masterId == 1 && !d.isActive);

然而,两者都返回相同的计数......这个实体框架调用产生了一些非常低效的丑陋 SQL:

exec sp_executesql N'SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM  [dbo].[childTable] AS [Extent1]
        INNER JOIN [dbo].[parentTable] AS [Extent2] ON [Extent1].[id] = [Extent2].[id]
        WHERE ([Extent2].[masterId] = @p__linq__0) AND ([Extent1].[isActive] <> 1)
    )  AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=1

区别在于简单的count(1) 语句的逻辑读取次数为 10 次,而实体框架语句的逻辑读取次数为 9200 次。我弄乱了 EF 的不同语法,此时它们都创建了相同的 T-SQL。

我是否在 EF 中遗漏了一些东西来有效地完成这个简单的计数?

【问题讨论】:

    标签: sql-server entity-framework-6


    【解决方案1】:

    所有三个查询都要求不同的东西。

    第一个查询不包含childTable.isActive = 1的条件。

    LINQ 表达式确实包含该条件。这是唯一一个似乎与您所说的意图相匹配的查询,“计算有多少“活动”子行,masterId 为 1”。

    生成的 SQL 具有 相反 的 isActive 条件:[Extent1].[isActive] &lt;&gt; 1。它似乎也在寻找不同的masterid

    虽然 Linq to SQL 肯定会产生一些糟糕的 SQL,但这不是问题所在。生成的 sql 仅在它使用冗长的别名和丑陋的参数名称的意义上是丑陋的。但是不等式以及不同的masterid 是问题所在。

    根据您的意图仔细检查您的代码,并确保您将苹果与苹果进行比较。

    【讨论】:

    • 我已经修正了我的问题中的错别字。抱歉,尝试将我的特定表名和 ID 名称转换为通用问题时发生了。但问题和问题仍然存在。
    • 您想要活动行还是非活动行?在问题文本中,您有“我想计算有多少“活动”子行”,但现在所有查询似乎都在询问非活动行。如果您确实想要非活动状态,您可以在 LINQ 中尝试&amp;&amp; d.isActive == false。这会将生成的不等式比较转换为等式比较。
    • d.isActive == false 和 !d.isActive 是一回事。
    • 好的,这太棒了,我学到了一些新东西,并引导我找到了实际的解决方案。我没有意识到我的“isActive”标志在数据库中可以为空,所以当 EF 创建 isActive1 时,它会导致更多的读取。一旦我删除了 nullable,IsActive1 和 IsActive=0 都会产生相同的性能,因为这是一个位列。谢谢!
    • 是的,可空位确实很有趣。我想有时需要它们(我同意 Codd,而不是 Date,关于关系中的空值),但我只是本能地讨厌可空位。
    猜你喜欢
    • 2020-12-15
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多