关于sql server:使用动态SQL vs参数调用sp_executesql的性能差异

Performance differences calling sp_executesql with dynamic SQL vs parameters

给出:

1
2
3
4
5
CREATE PROCEDURE [dbo].[my_storedproc]
  @param1 int, @param2 varchar(100)
AS
<<whatever>>
GO

这些不同的执行方法之间是否存在已知的性能差异?:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- Method #1:
declare @param1 int = 1
declare @param2 varchar(100) = 'hello'  
exec my_storedproc @param1, @param2

-- Method #2:  
exec my_storedproc @param1=1, @param2='hello'

-- Method #3:  
declare @param1 int = 1
declare @param2 varchar(100) = 'hello'  
declare @procname nvarchar(100) = N'my_storedproc @param1, @param2'
declare @params nvarchar(4000) = N'@param1 int, @param2 varchar(100)'  
exec sp_executesql @procname, @params, @param1, @param2

-- Method #4:  
declare @procname nvarchar(4000) = N'my_storedproc @param1=1, @param2=''hello'''
exec sp_executesql @procname

-- Method #5:  
declare @procname nvarchar(4000) = N'my_storedproc 1, ''hello'''
exec sp_executesql @procname

-- Method #6:  
declare @procname nvarchar(4000) = N'my_storedproc 1, ''hello'''
exec (@procname)

"你为什么问?"你问?我正在尝试找到一种完全基于元数据来一般地执行存储过程的方法,该控制存储过程将物理执行所有其他配置的(在元数据中)存储过程,除了元数据中定义的内容外,对它们一无所知。在此控制器SP中,我无法(从任何实际意义上)知道并声明可能必须调用的每个可能存储的proc所需的特定物理参数(及其所需的数据类型)-我正在尝试找到一种执行它们的方法完全通用,同时仍然希望保持良好的性能(重用查询计划等)。


这6个选项之间实际上应该没有性能差异,因为它们全部执行存储过程,而不是直接执行任何SQL语句。

但是,没有比在您自己的系统上测试性能更好的指示了。您已经有6个测试用例,因此尝试每个用例应该不难。

Within this controller SP, I cannot (in any practical sense) know and declare the specific physical parameters (with their required data types) required for every possible stored proc that might have to be called

为什么不呢?我看不到为什么无法基于以下两个查询之一的输出动态生成方法2和3的SQL:

1
2
3
4
5
6
7
8
SELECT OBJECT_NAME(sp.[object_id]), *
FROM   sys.parameters sp
WHERE  sp.[object_id] = OBJECT_ID(N'dbo.my_storedproc');

SELECT isp.*
FROM   INFORMATION_SCHEMA.PARAMETERS isp
WHERE  isp.[SPECIFIC_NAME] = N'my_storedproc'
AND    isp.[SPECIFIC_SCHEMA] = N'dbo';

使用该信息,您可以创建一个表,以包含每个proc的每个参数的各种参数值。实际上,您甚至可以将其设置为对所有变体都具有" global "值的某些参数,然后某些参数值就是特定proc的变体。