简体   繁体   English

SQL Server,Lazy Spool 在 View 中无休止地运行,但当我直接运行查询时却没有

[英]SQL Server, Lazy Spool runs endlessly in View but not when I run the query directly

I have a long query that feeds a daily Excel report.我有一个很长的查询,可以提供每日 Excel 报告。 It stopped working for some reason.它由于某种原因停止工作。 The saved view will run endlessly to the point where it crashes the SQL Server.保存的视图将无休止地运行到使 SQL Server 崩溃的程度。 But when I run the query itself (copied and pasted from the ALTER view), it actually runs fine and completes in about 17 seconds.但是当我运行查询本身(从 ALTER 视图复制和粘贴)时,它实际上运行良好并在大约 17 秒内完成。

I've narrowed down the culprit as this Lazy Spool.我已经缩小了这个 Lazy Spool 的罪魁祸首。 This is the live query stats running the query directly:这是直接运行查询的实时查询统计信息:

在此处输入图像描述

This is the view running:这是正在运行的视图:

在此处输入图像描述

I stopped it there.我在那里停下了。 It will run endlessly until the Lazy Spool has billions of lines and until it crashes the SQL server.它将无休止地运行,直到 Lazy Spool 拥有数十亿行,直到它使 SQL 服务器崩溃。

Not sure how much of the query I can share directly because of employer policies but does anybody have any idea why this is happening and how I can fix it?由于雇主政策,不确定我可以直接分享多少查询,但有人知道为什么会发生这种情况以及我该如何解决吗?

Your execution plan is not stable.您的执行计划不稳定。 You might be able to fix it temporarily by updating statistics on any/all of the tables in your view.您可以通过更新视图中任何/所有表的统计信息来临时修复它。 In the second screenshot the table is placed on the right side of a join.在第二个屏幕截图中,表格放置在联接的右侧。 Likely the best way to fix this would be to index your tbl_SO table to better support the join condition within the view.解决此问题的最佳方法可能是为您的tbl_SO表编制索引,以更好地支持视图中的连接条件。

You could also attempt to use OPTION (NO_PERFORMANCE_SPOOL) on your query to see if that fixes your issue.您还可以尝试在查询中使用OPTION (NO_PERFORMANCE_SPOOL)以查看是否可以解决您的问题。 That hint would have to go outside of your view.该提示必须超出您的视野。

EX: SELECT... FROM myView WHERE... OPTION (NO_PERFORMANCE_SPOOL);例如: SELECT... FROM myView WHERE... OPTION (NO_PERFORMANCE_SPOOL);

But when I run the query itself (copied and pasted from the ALTER view), it actually runs fine and completes in about 17 seconds.但是当我运行查询本身(从 ALTER 视图复制和粘贴)时,它实际上运行良好并在大约 17 秒内完成。

Have you tried running your view query with OPTION (RECOMPILE) ?您是否尝试过使用OPTION (RECOMPILE)运行视图查询? That's my best guess without the whole plan.这是我最好的猜测,没有整个计划。 It's possible that the view query is caching a bad plan (which would explain things).视图查询可能正在缓存一个错误的计划(这可以解释事情)。 A view (unindexed) is simply ad-hoc SQL that is stored for repeated use and therefore should create the exact same execution plan.视图(未编制索引)只是为重复使用而存储的临时 SQL,因此应该创建完全相同的执行计划。 At a birds eye level, the culprit is that you are getting a different execution plan for the view and the view code ran as ad-hoc.从鸟瞰的角度来看,罪魁祸首是您正在为视图获取不同的执行计划,并且视图代码是临时运行的。

Yes, the lazy spool appears to be a culprit but I suspect it is a symptom of the issue.是的,惰性线轴似乎罪魁祸首,但我怀疑这是问题的征兆 With the ad-hoc query you are retrieving 2,393,900 of 2,393,900 rows from your clustered index, the view query is fetching 8,383,512 of 2,393,900 rows, then the lazy spool is then queueing up 15,127,006 rows.使用临时查询,您从聚集索引中检索 2,393,900 行中的 2,393,900 行,视图查询从 2,393,900 行中检索 8,383,512 行,然后惰性假脱机排队 15,127,006 行。 This suggests that something dramatically different is happening behind the scenes, and causes me to even suspect that you are not running the exact same code.这表明幕后发生了一些截然不同的事情,让我什至怀疑你没有运行完全相同的代码。

This is a little advanced but in the article Nasty Fast PERCENT_RANK I discuss the lazy spools, when they are bad (often they are great) and how to alter your code to get the same result while avoiding a lazy spool.这有点高级,但在文章Nasty Fast PERCENT_RANK中我讨论了惰性假脱机,当它们不好时(通常它们很好)以及如何更改代码以获得相同的结果同时避免惰性假脱机。 That might help.这可能会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM