我可以通过在 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
。您可能可以使用带有子查询的一些“时髦”逻辑来强制它,但是它需要TOP
或OFFSET
上面的代码不包括。我也怀疑这些会产生相同的 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 配置导航属性
在.NET Core类库中使用EF Core迁移数据库到SQL Server