Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server中,如何允许SP中单个查询的多个执行计划,而无需每次重新编译?_Sql Server_Sql Execution Plan - Fatal编程技术网

Sql server 在SQL Server中,如何允许SP中单个查询的多个执行计划,而无需每次重新编译?

Sql server 在SQL Server中,如何允许SP中单个查询的多个执行计划,而无需每次重新编译?,sql-server,sql-execution-plan,Sql Server,Sql Execution Plan,在SQL Server中,允许SP中的查询存在多个执行计划而无需每次重新编译的最佳方式是什么 例如,我有一个例子,根据查询使用的临时表中的行数,查询计划会有很大的变化。由于没有令人满意的“一刀切”计划,而且每次重新编译都是不可接受的,因此我在几个IF语句中多次复制/粘贴(ick)SP中的主查询,迫使SQL引擎为每种情况提供自己的最佳计划。从性能上看,它似乎工作得很好,但感觉有点笨重。(我知道我可以同样地将此部分拆分为多个SP来执行相同的操作。)有更好的方法吗 IF @RowCount <

在SQL Server中,允许SP中的查询存在多个执行计划而无需每次重新编译的最佳方式是什么

例如,我有一个例子,根据查询使用的临时表中的行数,查询计划会有很大的变化。由于没有令人满意的“一刀切”计划,而且每次重新编译都是不可接受的,因此我在几个IF语句中多次复制/粘贴(ick)SP中的主查询,迫使SQL引擎为每种情况提供自己的最佳计划。从性能上看,它似乎工作得很好,但感觉有点笨重。(我知道我可以同样地将此部分拆分为多个SP来执行相同的操作。)有更好的方法吗

IF @RowCount < 1
    [paste query here]
ELSE IF @RowCount < 50
    [paste query here]
ELSE IF @RowCount < 200
    [paste query here]
ELSE
    [paste query here]
如果@RowCount<1
[在此处粘贴查询]
否则,如果@RowCount<50
[在此处粘贴查询]
否则,如果@RowCount<200
[在此处粘贴查询]
其他的
[在此处粘贴查询]
您可以在某些情况下使用,以创建针对某个参数的特定值(但不是多个计划本身)的计划。这允许您指定在创建执行计划时希望SQL Server使用的参数值。这是SQLServer2005以后的提示

还有一个SQL Server 2008以后的功能(明智地使用):

此提示指示查询优化器 使用标准算法 如果没有参数值,则始终使用 已传递给查询。 在这种情况下,优化器将 在所有可用的统计数据中 得出一个决定 用于修改的局部变量的值 生成queryplan应该是, 而不是看具体的 传递给的参数值 该查询由应用程序执行


也许还可以研究一下SQL Server 2005+具有语句级重新编译功能,并且更擅长处理这种分支。您仍然有一个计划,但可以在语句级别部分重新编译该计划

但它是丑陋的


我个人会选择@mitchwheat的选项,因为使用临时表的存储过程无论如何都有重新编译。请参见

One query/stored proc=任何给定时间的一个执行计划。我不知道有多个执行计划,这取决于参数。如果您有一些T-SQL代码,这些代码的执行计划从一组参数到另一组参数差异很大,那么您可能需要在单独的目录下创建该存储过程的多个实例names@marc_s_这有点不正确。SQLServer2005+具有语句级重新编译,并且更擅长处理这种分支。您仍然有一个计划,但该计划可以在语句级别部分重新编译。我很好奇为什么“with recompile”是不可接受的。我确实理解,在通常以微秒执行的查询中,编译是不可忽略的。但是对于一个需要几百毫秒的查询来说,与重复大型查询相比,它通常是值得的。optionrecompile做了很多很酷的事情,比如参数折叠,其中删除了计划的整个部分。在缓存多个不同的计划方面,这并不完全是您想要的,但我确实经常将其用于大型查询,而这些查询往往不会在循环中运行。谢谢,Mitch。我已经看过了这些,但由于没有“一刀切”的计划,它们不如我最后使用的“如果块”方法好。@John:看到Mitch的建议没有什么损失,但这些是表变量。与临时表不同,它们不会导致重新编译。