如何并行执行SQL过程中的子任务

Den*_*len 2 sql multithreading sqlclr

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

我的想法是拥有一个CLR管理程序,并在他们自己的线程上运行当天运行时间较长的程序,然后一旦快速完成,Thread.Join()长时间运行的线程等待所有实体完成前一天继续下一个.

下面是我的尝试作为最简单的事情,只适用于一个工作线程,并在该线程上调用Start不会导致调用静态方法.我在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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

Rem*_*anu 6

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

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

但很可能您的程序不需要显式并行.可以从显式用户控制的并行性中受益的T-SQL负载非常罕见,不值得一提(更不用说在并行任务中提取事务语义不仅仅是凡人).T-SQL可以利用内部语句并行性来并行处理数据,因此不需要显式并行.

所以你能更好地解释你真正想要解决的问题,也许我们可以提供帮助.