查询提示 'NO_PERFORMANCE_SPOOL' 被忽略?

Query hint 'NO_PERFORMANCE_SPOOL' being ignored?

我在供应商的大型 SQL 服务器数据库中工作,我的任务是从那里存储大量数据。服务器是 SQL Server 2017 (14.0.3391.2),查询 运行 的数据库设置为兼容级别 140。

我有几个查询,其中优化器决定在查询计划中使用 lazy/eager 索引假脱机。在过去(SQL Server 2016 forward)我已经能够使用 'NO_PERFORMANCE_SPOOL' 的查询提示轻松地防止这种情况发生。过去,这总是导致删除查询计划中的所有索引假脱机。 出于某种原因,当在数据库中应用该提示时,索引假脱机仍保留在执行计划中?我知道我正在查看实际的执行计划(允许查询后查看 SSMS 中提供的计划选中 'Include Actual Execution Plan' 执行)。我还没有找到任何其他记录在案的人声称他们正在发生这种情况的例子,所以这让我相信我错过了什么?我知道如果使用提供的提示无法生成计划,则可以忽略提示(甚至导致错误),但我无法想象这里是这种情况? 我不明白编译计划需要索引假脱机怎么可能?我的提示是否由于某种原因直接被忽略了?

所以我有点不知所措。我知道我可以使用其他方法(如重写查询或添加索引)来消除索引假脱机,但目前我对此不感兴趣。我只想知道为什么这个查询提示似乎被忽略了?

PS:对于任何想知道的人来说,当使用索引假脱机的计划时,这些查询会受到很大影响。该服务器通常受到 I/O 瓶颈和资源信号量等待(与内存授予相关。同样,不是我的 server/issue),因此索引假脱机结束成为一个大问题。

PS PS:我会 post 查询计划,但我认为数据 structure/naming 和生成的查询计划是供应商专有的。另外,我认为这里真的不需要它。如果有人认为这可能有帮助,那么我可以做更多的工作,看看我是否可以使用 AdventureWorks 或其他东西重新创建。

To quote the great @PaulWhite on this subject:

While an eager index spool may only appear on the inner side of an nested loops apply, it is not a “performance spool. An eager index spool cannot be disabled with trace flag 8690 or the NO_PERFORMANCE_SPOOL query hint.

性能 spool 是一个“lazy spool”,而不是 eager spool,并且使用不同的优化规则放置在那里。

他还说

In some respects, an eager index spool is the ultimate missing index suggestion

因此我强烈建议您索引 table 以移除线轴