【问题标题】:Executing stored procedures in Parallel并行执行存储过程
【发布时间】:2015-03-22 11:31:05
【问题描述】:

我有 35 个存储过程需要并行运行以减少执行时间。

我遇到了代理工作的概念here

链接建议使用这段代码来实现:

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

它是如何在循环中调用的吗?但我相信循环的下一次迭代只有在最后一次执行完成时才会开始,那么它是如何并行运行的呢?

【问题讨论】:

  • sp_start_job 只是启动作业,它不会等到它完成,这就是该脚本背后的想法
  • @Simran,您可以考虑使用 Service Broker 来完成此任务,而不是 SQL Server 代理。这将提供对并发 proc 执行数量的更多控制,否则可能会使服务器不堪重负。

标签: sql-server tsql stored-procedures


【解决方案1】:

顺便说一句,为什么要并行执行 35 个过程?对我来说,这个要求听起来有点不切实际。

即使您同时执行两个存储过程,也不能保证它们会并行。

执行的并行度取决于查询成本、MXDOP(最大并行度)、并行度阈值等其他因素。

这些属性在服务器级配置上进行操作(除了可以在查询中指定的 MAXDOP。

我不能详细说明,但我的建议是,不要依赖并行性,以不依赖于并行查询的方式编写代码,而且查询的同时执行也是通过事务处理的。

就像提示要并行执行 35 个过程一样,您需要 Sql Server 上的 35 个内核并将 MAXDOP 设置为 1,然后让它们在准确的时间执行 35 个过程。对我来说似乎有很多不切实际的要求:)

【讨论】:

  • 所有这些都不会并行执行。只是它们中的一些块会继续下去。
  • 如果你想提高性能,并行运行它们不一定有帮助。如果你因为糟糕的代码而遇到资源瓶颈,这肯定无济于事
  • 任何有关并行 sp 执行的 mircrosoft 文档链接
【解决方案2】:

你是对的。下一次迭代将在最后一次完成时开始。但是在这里,您在这些迭代中运行作业,而不是实际语句。所以想象它像 sp_start_job 以异步方式调用。它只会开始工作并立即返回。工作本身可能会继续执行它的步骤。

【讨论】:

    【解决方案3】:

    最好、最简单的方法是创建一个具有 35 个并行执行 SQL 任务的 SSIS 项目,然后执行该作业。使用 SSIS 执行此操作的学习曲线是一两个小时,您可以让 SQL Server 使用尽可能多的资源来尽可能快地执行任务。您不必乱用 maxops 或其他任何东西 - SSIS 会为您完成。

    要查看执行 SSIS 作业的不同方法,请尝试以下链接: http://www.mssqltips.com/sqlservertip/1775/different-ways-to-execute-a-sql-server-ssis-package/

    【讨论】:

    • 听起来很有趣。您能否指定 ssis 的下载链接?我一直在寻找它,但没有运气。
    • 它是一个免费工具(随任何付费版本的 SQL Server 一起提供),它的全名是 SQL Server Integration Services。要在 SQL Server 2012 及更高版本上创建包,请参阅:msdn.microsoft.com/en-us/library/ms169917.aspx
    • 哦,我的不是付费版。我希望 SQL Server 代理服务没有它也能正常工作?我一直在尝试使用 sql server 代理,但它也没有启动。
    • 您需要 SQL Server 的付费版本才能使用 SQL Server 代理。 EXPRESS 不让你
    猜你喜欢
    • 2021-10-11
    • 2021-08-25
    • 1970-01-01
    • 2018-03-12
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多