实体框架生成的 SQL - SELECT TOP (X) 比 SELECT 多花费 500% 的时间
我正在开发一个使用实体框架的 MVC 网站。我是一名前 ADO.Net 表单人员,所以这对我来说有点新鲜。我的 EDM 当前由一个抽象的“产品”实体组成,该实体有 5 个继承自它的不同“类型”实体。 “产品”实体映射到 7 或 8 个表,并具有大约 50 个属性,从“产品”继承的每个“类型”都有大约 5 到 20 个扩展“产品”的额外属性。我注意到,当我在 IQueryable 上使用 .Take 扩展方法将数据返回到 Telerik 网格时,返回数据所花费的时间明显比我只是使用 .ToList 贪婪地将整个集合返回到内存时要长。
当我运行 SQL Profiler 来查看究竟发生了什么时,我发现了以下内容。
exec sp_executesql N'SELECT TOP (20)
[Project12].[C1] AS [C1],
[Project12].[C2] AS [C2],
[Project12].[C3] AS [C3],
etc ... 508 SQL lines follow, too much to paste here unfortunately.
执行需要 500 毫秒。然而,以下内容:
exec sp_executesql N'SELECT
[Project12].[C1] AS [C1],
[Project12].[C2] AS [C2],
[Project12].[C3] AS [C3],
etc ...
执行大约需要 80 毫秒。
因此,根据上述逻辑判断,我应该放弃延迟执行,并且每次用户更改页面时......将整个数据集放入内存(500 行左右)。有谁对发生了什么以及为什么 SQL Server 2005 会这样表现有任何建议吗?
编辑
我已将完整的SQL放在http://pastebin.com/rAGGSScA .难道 SQL 正在缓存“完整”选择,而不缓存“TOP (20)”结果?
SELECT 的客户端统计信息
SELECT TOP (20) 的客户端统计信息 >
I am developing an MVC website that uses the Entity Framework. I am an ex ADO.Net forms man, so it's all a bit new to me. My EDM currently consists of an abstract "Product" Entity, which has 5 different "type" Entities that inherit from it. The "Product" Entity maps to 7 or 8 tables and has about 50 properties, each "type" that inherits from a "Product" has some 5 to 20 extra properties that extend a "Product". I notice that when I used the .Take extension method on the IQueryable to return data to a Telerik grid, it was taking noticably longer to return data than if I just greedily returned the whole collection to memory using .ToList.
When I ran SQL Profiler to see just what the devil was going on, here is what I found.
exec sp_executesql N'SELECT TOP (20)
[Project12].[C1] AS [C1],
[Project12].[C2] AS [C2],
[Project12].[C3] AS [C3],
etc ... 508 SQL lines follow, too much to paste here unfortunately.
Takes 500 milliseconds to execute. The following however:
exec sp_executesql N'SELECT
[Project12].[C1] AS [C1],
[Project12].[C2] AS [C2],
[Project12].[C3] AS [C3],
etc ...
Takes around 80 milliseconds to execute.
So, judging by the above logic, I should ditch deferred execution, and every time the user changes page... take the entire dataset down into memory (500 rows or so). Does anyone have any suggestions what is going on and why SQL Server 2005 is behaving in this way?
EDIT
I've placed the full SQL on http://pastebin.com/rAGGSScA . Could it be that SQL is caching the "full" select, and not caching the "TOP (20)" results?
Client Statistics for SELECT
Client Statistics for SELECT TOP (20)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在“后面的 508 条 SQL 行”中的某个位置将有一个 ORDER BY 子句。通过强制对查询进行“TOP (N)”评估,您将强制服务器更早地评估此 order by 子句,并在 之前计算所有 结果(包括它们的顺序)任何都可以显示。您可能最终会得到一个完全不同的执行计划,甚至可能使索引无效(或与不太理想的索引匹配)。如果没有“TOP (n)”子句,服务器一旦知道将使用记录就可以开始显示结果。
Somewhere in your "508 SQL lines [that] follow" will be an ORDER BY clause. By forcing a "TOP (N)" evaluation on the query, you are forcing the server to evaluate for this order by clause much earlier and compute all of the results (including their order) before any can be shown. You'll likely end up with an entirely different execution plan, and may even void an index (or match of up with a less-desirable index). Without a "TOP (n)" clause, the server can begin showing results as soon as it knows a record will be used.
如果它们都有 ORDER BY ,那么我的猜测是,慢速计划使用的是不同的计划,该计划通常效率较低,但以所需的排序顺序输出行,而快速计划使用不同的计划它以未排序的顺序输出行,并具有显式的
SORT
步骤。可能的情况是,当使用较慢的计划时,SQL Server 需要处理超过 20 行才能获得输出的
TOP 20
(因为许多行被连接或 where 子句条件消除)并且它没有正确估计这个因素,导致它错误地认为慢速计划比快速计划便宜。If they both have an
ORDER BY
then my guess is that the slow one is using a different plan that is less generally efficient but that outputs the rows in the desired sort order and the fast plan uses a different plan which outputs the rows in non sorted order and has an explicitSORT
step.It may be the case that when using the slower plan SQL Server needs to process many more than 20 rows in order to get the
TOP 20
for output (as many are eliminated by joins or where clause criteria) and it does not estimate this factor correctly leading it to incorrectly cost the slow plan as being cheaper than the fast one.