Sql server 为什么在通过sp_executeSQL过程执行时,相同的SQL查询会产生不同的执行计划?

Sql server 为什么在通过sp_executeSQL过程执行时,相同的SQL查询会产生不同的执行计划?,sql-server,tsql,sql-execution-plan,sp-executesql,Sql Server,Tsql,Sql Execution Plan,Sp Executesql,正如标题所述,我不明白为什么sp_executeSQL会生成与从Sql Management Studio运行查询完全不同的执行计划 当从SQL management Studio运行时,我正在讨论的查询需要3秒钟,而在management Studio中通过sp_executeSQL运行查询需要5分钟 我已经更新了统计数据,并查看了索引,但事实仍然留在我的脑海中,sp_executeSQL的执行计划比直接从我的管理工作室运行sql糟糕得多 所以我的问题是:为什么以这两种不同的方式运行查询的执行

正如标题所述,我不明白为什么sp_executeSQL会生成与从Sql Management Studio运行查询完全不同的执行计划

当从SQL management Studio运行时,我正在讨论的查询需要3秒钟,而在management Studio中通过sp_executeSQL运行查询需要5分钟

我已经更新了统计数据,并查看了索引,但事实仍然留在我的脑海中,sp_executeSQL的执行计划比直接从我的管理工作室运行sql糟糕得多

所以我的问题是:为什么以这两种不同的方式运行查询的执行计划会有如此大的差异


谢谢

考虑一下。执行存储过程时,此过程将有自己的执行计划。当您执行查询语句时,它也会有自己的执行计划。现在,在使用sp_executeSQL时,您正在运行此存储过程以动态执行查询。所以本质上,它的执行计划是sp_executeSQL和您的查询的组合

基本上,
同一程序可能有多个[执行]计划

请注意,我已经看到了有关sp_executeSQL程序的执行计划的其他问题。我只是没有看到关于为什么这个过程会生成与management studio或自定义存储过程不同的计划的解释。它将生成与自定义存储过程完全相同的计划(AFAIK)。对于存储过程和sp_executesql来说,计划都是根据它看到的第一组参数的值来编译的。当您的查询具有常量且计划未自动参数化时,SQL Server有时可以使用矛盾检测来不执行计划的一部分,还将对这些特定值使用基数估计。完全理解这一点,但执行计划是查询的组合,每个查询都有自己的步骤。问题是,查询4与sp_executeSQL调用和sql management studioI中运行的特殊查询完全不同,这两个查询之间的查询文本完全相同。我无法阅读您链接的整篇文章,但他发表的声明是我问题的关键:“虽然程序是一次性编译的,但每个查询都会自行优化,并且不会试图分析执行流程。“因此,基本上,因为查询是在sp_executeSQL中执行的,所以它单独优化了查询,对我来说,无论我如何提交查询,两次执行都应该有完全相同的执行查询计划。事实并非如此。这有意义吗?(不过我还在继续读这篇文章!)啊哈!所以不要理会我之前的评论。虽然独立地处理单个语句,但会考虑在生成执行计划时使用提供的任何参数。又名参数嗅探。在我的例子中,虽然参数是以null形式传递的,但我有if条件将它们设置为if null。因为参数永远不会为null,但是查询执行计划生成器假设它们为null,所以引擎在创建execution plan.TL时没有正确地考虑逻辑;DR:在查询中使用ISNULL或COALESCE方法来正确分配默认值if null,而不是在查询之前使用if语句(希望您不介意,我想给您一个答案,因为这篇文章有答案,但我想在这个答案中添加更多细节,以便更好地描述我遇到的场景)。谢谢