gpt4 book ai didi

c# - EF 排序和分页 - 两次订购速度慢?

转载 作者:太空宇宙 更新时间:2023-11-03 18:30:00 24 4
gpt4 key购买 nike

我有一个简单的实体,我的 SQL Sever 2012 数据库中有 100,000 个实体:

public class Entity
{
public int Id { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
}

我想在网格中显示这些内容,因为 100,000 个页面太多而无法在一个屏幕上显示(而且效率不高)。网格应该允许排序和过滤——显然所有这 3 个操作最好在服务器上完成,EF 应该翻译这些。

因此,让我们获取按 Field1 排序的 500 页中的第二页:

var items = context.Entities.OrderBy(e => e.Field1).Skip(500).Take(500);

执行此查询时,需要12 秒!所以我挖了一下,发现它的翻译如下:

SELECT TOP (500) [Extent1].[Id]     AS [Id],
[Extent1].[Field1] AS [Field1],
[Extent1].[Field2] AS [Field2]
FROM (SELECT [Extent1].[Id] AS [Id],
[Extent1].[Field1] AS [Field1],
[Extent1].[Field2] AS [Field2],
row_number() OVER (ORDER BY [Extent1].[Field1] ASC) AS [row_number]
FROM [dbo].[Costs] AS [Extent1]) AS [Extent1]
WHERE [Extent1].[row_number] > 500
ORDER BY [Extent1].[Field1] ASC

确定这是被排序了两次?我不是 SQL 专家,但子查询按 Field1 排序并将此排序分配给 row_number。然后我们将 TOP 500 row_numbers 超过 500 以获得第 2 页最多 500 行。我们不需要再次按 Field1 对结果进行排序。

如果我取出最后的 ORDER BY [Extent1].[Field1] ASC,查询结果似乎是一样的,执行时间下降到大约 150 毫秒。

所以,显然 150 毫秒优于 12 秒 - 我做错了什么吗?我能做些什么来解决这个问题吗?

更新

两者的查询计划是相同的。排序工具提示的唯一区别是 12 秒查询的“实际行数”为 4,604,而 150 毫秒查询的“实际行数”为 1,134。我要补充一点,这是从 15 个单词的固定列表生成的数据(对于此测试)- 即 Field1 包含 15 个值中的 1 个,因此基本上有 15 组 6,666 行。

Query Plan

( click for larger image )

SQL Server 2012 backup

最佳答案

这是由于 TOP 和 Gather Streams 组合时 SQL Server 中的错误/特性所致。 索引将修复它,禁用并行性(全局,或针对该用户,或针对查询)也是如此。线索是 Gather Streams 溢出到 tempdb,这是一种极其罕见的情况。 http://web.archive.org/web/20180220120719/http://sqlblog.com:80/blogs/paul_white/archive/2012/05/03/parallel-row-goals-gone-rogue.aspx这是 500 级的东西。

请注意,您不能省略最后的 ORDER BY,因为这会使结果的顺序不确定。

关于c# - EF 排序和分页 - 两次订购速度慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24383874/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com