2010-11-30 60 views
2

我有一个过程分析来自一个系统的审计数据以构建另一个系统的报告数据。有一个管理程序循环每天进行分析,并在当前迭代当天调用实体特定的过程。一些实体需要不到一秒的时间来处理,而其他实体可能需要几分钟时间。像在t-sql中一样连续运行,cpu利用率从未在16核心服务器上高于8%。每个实体特定的过程都不依赖于其他实体,只是当天的所有实体在第二天开始前已经完成。如何在SQL过程中并行执行子任务

我的想法是有一个CLR管理过程,并开始在自己的线程上运行一天的较长运行过程,然后一旦快速完成,Thread.Join()长时间运行的线程等待所有实体在继续前进之前完成那一天。

下面是我尝试的最简单的事情,可以只为一个工作线程工作,并调用该线程上的开始不会导致被调用的静态方法。我已经在HelloWorld方法中设置了一个断点,并且它从未被击中。

我已经在控制台应用程序中尝试过非常类似的东西,并且它在AsyncHelloWorld的开始处的注释掉行中的同一线程上调用它。 SQL CLR程序中的线程有什么不同吗?

using System.Threading; 
using Microsoft.SqlServer.Server; 

public partial class StoredProcedures 
{ 
    [SqlProcedure] 
    public static void AsyncHelloWorld() 
    { 
     // HelloWorld(SqlContext.Pipe); 

     var worker = new Thread(HelloWorld); 
     worker.Start(SqlContext.Pipe); 
     worker.Join(); 
    } 

    public static void HelloWorld(object o) 
    { 
     var pipe = o as SqlPipe; 

     if (pipe != null) 
      pipe.Send("Hello World!"); 
    } 
} 
+0

你是否有错误,或者什么都没有发生? – Nate 2010-11-30 21:20:01

+0

HelloWorld方法永远不会被调用。 – 2010-11-30 21:51:18

回答

6

你绝对不能这样做。 SqlPipe与你被调用的线程的上下文非常紧密相关。虽然技术上可以从SQLCRL启动线程,但这些线程必须与原始线程的调用者进行所有交互。但即使如此,在SQL托管环境中启动CLR线程也是一个坏主意(我不会详细说明为什么)。

相反,将您的逻辑分成可以并行调用的过程,并从客户端并行调用这些过程。您可以使用Asynchronous procedure execution作为以异步方式启动的调度过程模式,并且基于队列的激活已通过MAX_QUEUE_READERS设置内置了对并行性的支持。

但很可能您的过程不需要显式并行性。 T-SQL加载比可以受益于明确的用户控制并行性非常少见,不值得一提(更不用说拉动并行任务中的事务语义超越单纯的凡人)。 T-SQL可以利用内部语句并行性来并行处理数据,所以从不需要显式并行。

所以你最好解释一下你是什么真的试图解决,也许我们可以帮助。