按顺序或并行启动存储过程

11
我们有一个每晚运行的存储过程,随后又启动了许多其他存储过程。其中一些存储过程可以与其他存储过程并行运行。请问:
  • 如何告诉SQL Server存储过程应该并行运行还是串行运行?
  • 如果同时运行它们,会有什么影响,考虑到已经确定这些进程不会竞争表访问或锁定,只涉及总磁盘IO和内存。大部分情况下,它们甚至不使用相同的表。
  • 如果其中某些存储过程是相同的存储过程,只是具有不同的参数,这会有影响吗?
  • 如果我异步地启动一对存储过程,是否有好的系统在等待两者完成之后,或者我需要使每个存储过程设置一个标志,并使用WAITFOR DELAY 定期检查和轮询标志?
目前我们还在使用SQL Server 2000。
附带说明:这很重要,因为主要存储过程是响应从主机系统转储到服务器完成后启动的。主机转储每晚除去约2小时,我们无法控制。因此,我们不断尝试缩短处理时间。
4个回答

14

最近我不得不做这方面的研究,所以找到了这个旧问题,需要更全面的答案。要明确一点:TSQL本身不能异步启动其他TSQL操作

这并不意味着您没有仍有许多选项(其他答案中提到的某些选项):

  • 自定义应用程序: 使用异步方法在所选语言中编写简单的自定义应用程序。在每个应用程序线程上调用SQL存储过程。
  • SQL代理作业: 创建多个SQL作业,并使用sp_start_job从您的过程异步启动它们。可以使用未记录的函数xp_sqlagent_enum_jobs检查它们是否已完成,如Gregory A. Larsen在这篇优秀的文章中所述。 (或者像Chris建议的那样,让作业本身更新您自己的JOB_PROGRESS表。)即使它们使用不同的参数运行相同的存储过程,您也必须为您预计运行的每个并行进程创建单独的作业。
  • OLE Automation: 使用sp_oacreatesp_oamethod启动调用其他存储过程的新进程,如Gregory A. Larsen在这篇文章中所述。
  • DTS Package: 创建一个DTS或SSIS包,具有简单的分支任务流。 DTS将在单个spid中启动任务。
  • Service Broker: 如果您使用SQL2005+,请考虑使用Service Broker
  • CLR并行执行: 使用CLR命令Parallel_AddSqlParallel_Execute,如Alan Kaplan在这篇文章中所述(SQL2005+ only)。
  • 预定的Windows任务: 仅列出以保证完整性,但我不喜欢这个选项。
  • 我对服务代理或CLR没有太多经验,因此无法对这些选项进行评论。如果是我的话,在简单的情况下可能会使用多个作业,在更复杂的情况下可能会使用DTS / SSIS包。

    最后一条评论: SQL已经尝试在任何时候都尽可能并行化各个操作。这意味着同时运行2个任务而不是一个接一个地运行是不能保证它会更快完成。请仔细测试以确定是否实际上改进了任何东西。

    我们有一个开发人员创建了一个DTS包,同时运行8个任务。不幸的是,那只是一个4-CPU服务器 :)

    *假设默认设置。这可以通过修改服务器的最大并行度或亲和掩码,或使用MAXDOP查询提示来进行修改。


    1
    一个关于服务代理方面的好链接。http://rusanu.com/2009/08/05/asynchronous-procedure-execution/ - Martin Smith

    3
    创建两个SQL Server代理作业,每个作业运行一个特定的存储过程。
    然后在主存储过程中启动这些作业。
    我能想到的唯一等待的方法是:如果您有一个状态表,每个存储过程完成时都会更新该表。
    然后另一个作业可以轮询该表以获取总体完成情况并启动最终的存储过程。或者,您可以在此表上设置触发器。
    内存影响完全取决于您的环境..
    更新: 如果您可以访问任务系统..那么您可以采用相同的方法。只需让Windows执行多个任务,每个任务负责一个存储过程。然后在状态表上使用触发器,在所有任务完成时启动某些内容。
    更新2: 此外,如果您愿意创建一个新应用程序,您可以将所有逻辑放在一个单独的exe文件中...

    听起来这个方法可能可行,但是在这里创建工作并不被鼓励。即使我在这里谈论的主要过程也不是一个工作——它通过一个独立的程序从Windows计划任务运行。 - Joel Coehoorn
    “.exe” 这个想法更有吸引力,但我仍然想知道是否有可能以合理的方式在 SQL Server 本身中实现这一点。如果不行的话,它应该是可以的。 - Joel Coehoorn

    2

    您需要将过夜 sprocs 转移到作业中。SQL Server 作业控制将让您完成所有所需的调度。


    2
    你可能想考虑使用DTS(可以作为SQL Agent作业运行)。它将允许您对需要等待其他存储过程完成以及可以并行运行的存储过程进行精细控制。如果需要,您还可以将DTS包作为EXE从自己的调度软件中运行。
    注意:您需要创建多个连接对象的副本,以允许调用并行运行。即使您没有明确添加依赖关系,两个使用相同连接对象的调用仍将相互阻塞。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接