我可以通过在 EF Core 和 SQL Server 中的 OrderBy() 之前使用 Where() 来提高查询的性能吗?

Posted

技术标签:

【中文标题】我可以通过在 EF Core 和 SQL Server 中的 OrderBy() 之前使用 Where() 来提高查询的性能吗?【英文标题】:Can I increase the performance of my query by using Where() before OrderBy() in EF Core and SQL Server? 【发布时间】:2021-06-23 08:28:06 【问题描述】:

我将 Entity Framework Core 与 MS SQL Server 一起使用,我的 dbContext 上有以下查询:

var list = await dbContext.MyTable
                          .OrderByDescending(x => x.Timestamp)
                          .Where(x => x.Something == someVar && x.Succeeded)
                          .ToListAsync()
                          .ConfigureAwait(false);

如果我将OrderByDescending()Where() 之前移到Where() 之后,性能会有什么不同吗?

像这样:

var list = await dbContext.MyTable
                          .Where(x => x.Something == someVar && x.Succeeded)
                          .OrderByDescending(x => x.Timestamp)
                          .ToListAsync()
                          .ConfigureAwait(false);

【问题讨论】:

你有代码,你有数据。您是否尝试过自己进行基准测试,看看是否有什么不同......?话虽这么说:我的猜测是 EF 足够聪明,无论如何都可以优化它并生成相同的 SQL 代码。你也可以用调试器检查那个 为什么不race your horses? 我什至不确定 EF 是否能够生成 RDBMS 在 WHERE @FranzGleichmann 之前应用 ORDER BY 的计划。在 T-SQL 中,WHERE 是logically processed 之前 ORDER BY。您可能可以使用带有子查询的一些“时髦”逻辑来强制它,但是它需要TOPOFFSET 上面的代码不包括。我也怀疑这些会产生相同的 SQL。 提问前为什么不看一下生成的SQL? 对于 SQL 性能帮助,您需要向我们展示两个生成的 SQL 查询,并通过brentozar.com/pastetheplan 共享执行计划。还请添加表和索引定义。我想如果没有Take/Skip 或某种形式的加入,几乎不可能有所作为。 【参考方案1】:

按照建议,我进行了一些基准测试。我为每次运行使用了一个新的 InMemoryDatabase,并在其中填充了 100 万个条目,每个条目都有不同的时间戳。我运行这两个查询 5 次以获得更好的比较基准。

OrderBy() 放在Where() 之前的结果:

1651ms
1096ms
1172ms
1214ms
1391ms

OrderBy() 放在Where() 之后的结果:

735ms
1026ms
894ms
1110ms
939ms

似乎语句的顺序确实有影响,尽管影响很小。

【讨论】:

你问了一个关于 SQL Server 差异的问题。那么为什么不使用 SQL Server 进行测试呢?你不会看到任何区别。

以上是关于我可以通过在 EF Core 和 SQL Server 中的 OrderBy() 之前使用 Where() 来提高查询的性能吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF Core 5 中为自定义 SQL 配置导航属性

EF Core 执行sql语句

ASP - 在启动时核心迁移 EF Core SQL DB

在.NET Core类库中使用EF Core迁移数据库到SQL Server

使用托管标识与 Azure SQL 的 EF Core 连接

带有 EF Core 和内存数据库提供程序的原始 sql