并行执行存储过程
Executing stored procedures in Parallel
我有 35 个存储过程需要并行 运行 以减少执行时间。
我遇到了代理工作的概念 here。
link建议使用这段代码来实现:
CREATE PROCEDURE ExecuteSQL_ByAgentJob_usp(
@SqlStatemet VARCHAR(4000),
@SPNameOrStmntTitle VARCHAR(100),
@JobRunningUser VARCHAR(100) = NULL,
@JobIdOut UNIQUEIDENTIFIER OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @JobId UNIQUEIDENTIFIER,
@JobName VARCHAR(250) = NULL,
@DBName VARCHAR(100) = DB_NAME(),
@ServerName VARCHAR(100) = @@SERVERNAME
--Creating Unique Job Name by combining @SPNameOrStmntTitle and a GUID.
SET @JobName = @SPNameOrStmntTitle + '_' + CONVERT(VARCHAR(64), NEWID())
--Currently logged user name will be used to execute the job if not provided one.
IF @JobRunningUser IS NULL
SET @JobRunningUser = SUSER_NAME()
--Adds a new job executed by the SQLServerAgent service
EXECUTE msdb..sp_add_job @job_name = @JobName, @owner_login_name = @JobRunningUser,
@job_id = @JobId OUTPUT
--Targets the specified job at the specified server
EXECUTE msdb..sp_add_jobserver @job_id = @JobId, @server_name = @ServerName
--Tell job for its about its first step.
EXECUTE msdb..sp_add_jobstep @job_id = @JobId, @step_name = 'Step1', @command
= @SqlStatemet,@database_name = @DBName, @on_success_action = 3
--Preparing the command to delete the job immediately after executing the statements
DECLARE @sql VARCHAR(250) = 'execute msdb..sp_delete_job @job_name=''' + @JobName + ''''
EXECUTE msdb..sp_add_jobstep @job_id = @JobId, @step_name = 'Step2', @command = @sql
--Run the job
EXECUTE msdb..sp_start_job @job_id = @JobId
--Return the Job via output param.
SET @JobIdOut = @JobId
END
尽管看了一遍又一遍,我仍然不明白它的哪一部分有助于并行执行存储过程?如果可能的话,请阐明它。我非常想知道脚本的哪一部分具有这种魔力。
它是这样称呼的:
SET @Itr = 1 --Seeting the initial value.
SET @RecCount = (
SELECT COUNT(*)
FROM @Scripts
)
-----------------PART3------------------------------------
WHILE (@Itr <= @RecCount)
BEGIN
SELECT @sql = t.Script
FROM @Scripts t
WHERE id = @Itr
--Just o identify the script name getting first 10 char of the SP
SET @ScriptTitle = LEFT(REPLACE(@sql, 'EXEC ', ''), 10)
EXEC ExecuteSQL_ByAgentJob_usp
@SqlStatemet = @sql,
@SPNameOrStmntTitle = @ScriptTitle,
@JobRunningUser = 'sa',
@JobIdOut = @JobId OUTPUT
在循环中是这样调用的吗?但我相信循环的下一次迭代只会在最后一次执行完后才开始,所以它为什么会 运行s 并行?
你是对的。下一次迭代将在最后一次完成时开始。但是在这里,您是那些迭代中的 运行 个作业,而不是实际的语句。所以想象一下 sp_start_job 以异步方式调用。它会立即开始工作并return。工作本身可能会继续执行它的步骤。
附带说明一下,您为什么要并行执行 35 个过程?对我来说,这个要求听起来有点不切实际。
即使您同时执行两个存储过程,也不能保证它们会并行。
执行的并行度取决于其他因素,例如查询成本、MXDOP(最大并行度)、并行度阈值等。
这些属性在服务器级配置上进行操作(除了可以在查询中指定的 MAXDOP。
我不能说太多细节,但我的建议是,不要依赖于并行性,以一种不依赖于并行查询的方式编写你的代码,而且查询的同时执行是通过事务处理的。
正如提示要并行执行 35 个程序,您需要 Sql 服务器上有 35 个内核,并将 MAXDOP 设置为 1,然后让它们同时执行 35 个程序。对我来说似乎有很多不切实际的要求:)
最好、最简单的方法是创建一个 SSIS 项目,其中包含 35 个并行执行 SQL 任务,然后执行该作业。使用 SSIS 执行此操作的学习曲线是一两个小时,您可以让 SQL 服务器使用尽可能多的资源来尽快执行任务。您不必乱用 maxops 或其他任何东西 - SSIS 会为您完成。
要查看执行 SSIS 作业的不同方式,试试这个 link:
http://www.mssqltips.com/sqlservertip/1775/different-ways-to-execute-a-sql-server-ssis-package/
我有 35 个存储过程需要并行 运行 以减少执行时间。
我遇到了代理工作的概念 here。
link建议使用这段代码来实现:
CREATE PROCEDURE ExecuteSQL_ByAgentJob_usp(
@SqlStatemet VARCHAR(4000),
@SPNameOrStmntTitle VARCHAR(100),
@JobRunningUser VARCHAR(100) = NULL,
@JobIdOut UNIQUEIDENTIFIER OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @JobId UNIQUEIDENTIFIER,
@JobName VARCHAR(250) = NULL,
@DBName VARCHAR(100) = DB_NAME(),
@ServerName VARCHAR(100) = @@SERVERNAME
--Creating Unique Job Name by combining @SPNameOrStmntTitle and a GUID.
SET @JobName = @SPNameOrStmntTitle + '_' + CONVERT(VARCHAR(64), NEWID())
--Currently logged user name will be used to execute the job if not provided one.
IF @JobRunningUser IS NULL
SET @JobRunningUser = SUSER_NAME()
--Adds a new job executed by the SQLServerAgent service
EXECUTE msdb..sp_add_job @job_name = @JobName, @owner_login_name = @JobRunningUser,
@job_id = @JobId OUTPUT
--Targets the specified job at the specified server
EXECUTE msdb..sp_add_jobserver @job_id = @JobId, @server_name = @ServerName
--Tell job for its about its first step.
EXECUTE msdb..sp_add_jobstep @job_id = @JobId, @step_name = 'Step1', @command
= @SqlStatemet,@database_name = @DBName, @on_success_action = 3
--Preparing the command to delete the job immediately after executing the statements
DECLARE @sql VARCHAR(250) = 'execute msdb..sp_delete_job @job_name=''' + @JobName + ''''
EXECUTE msdb..sp_add_jobstep @job_id = @JobId, @step_name = 'Step2', @command = @sql
--Run the job
EXECUTE msdb..sp_start_job @job_id = @JobId
--Return the Job via output param.
SET @JobIdOut = @JobId
END
尽管看了一遍又一遍,我仍然不明白它的哪一部分有助于并行执行存储过程?如果可能的话,请阐明它。我非常想知道脚本的哪一部分具有这种魔力。
它是这样称呼的:
SET @Itr = 1 --Seeting the initial value.
SET @RecCount = (
SELECT COUNT(*)
FROM @Scripts
)
-----------------PART3------------------------------------
WHILE (@Itr <= @RecCount)
BEGIN
SELECT @sql = t.Script
FROM @Scripts t
WHERE id = @Itr
--Just o identify the script name getting first 10 char of the SP
SET @ScriptTitle = LEFT(REPLACE(@sql, 'EXEC ', ''), 10)
EXEC ExecuteSQL_ByAgentJob_usp
@SqlStatemet = @sql,
@SPNameOrStmntTitle = @ScriptTitle,
@JobRunningUser = 'sa',
@JobIdOut = @JobId OUTPUT
在循环中是这样调用的吗?但我相信循环的下一次迭代只会在最后一次执行完后才开始,所以它为什么会 运行s 并行?
你是对的。下一次迭代将在最后一次完成时开始。但是在这里,您是那些迭代中的 运行 个作业,而不是实际的语句。所以想象一下 sp_start_job 以异步方式调用。它会立即开始工作并return。工作本身可能会继续执行它的步骤。
附带说明一下,您为什么要并行执行 35 个过程?对我来说,这个要求听起来有点不切实际。
即使您同时执行两个存储过程,也不能保证它们会并行。
执行的并行度取决于其他因素,例如查询成本、MXDOP(最大并行度)、并行度阈值等。
这些属性在服务器级配置上进行操作(除了可以在查询中指定的 MAXDOP。
我不能说太多细节,但我的建议是,不要依赖于并行性,以一种不依赖于并行查询的方式编写你的代码,而且查询的同时执行是通过事务处理的。
正如提示要并行执行 35 个程序,您需要 Sql 服务器上有 35 个内核,并将 MAXDOP 设置为 1,然后让它们同时执行 35 个程序。对我来说似乎有很多不切实际的要求:)
最好、最简单的方法是创建一个 SSIS 项目,其中包含 35 个并行执行 SQL 任务,然后执行该作业。使用 SSIS 执行此操作的学习曲线是一两个小时,您可以让 SQL 服务器使用尽可能多的资源来尽快执行任务。您不必乱用 maxops 或其他任何东西 - SSIS 会为您完成。
要查看执行 SSIS 作业的不同方式,试试这个 link: http://www.mssqltips.com/sqlservertip/1775/different-ways-to-execute-a-sql-server-ssis-package/