2010-11-30 6 views
2

J'ai un processus qui analyse les données d'audit d'un système pour créer des données de rapport pour un autre système. Il y a une procédure de gestion qui boucle pour chaque jour à analyser et appelle une procédure spécifique à l'entité avec le jour de l'itération en cours. Certaines entités prennent moins d'une seconde à traiter tandis que d'autres peuvent prendre quelques minutes. Fonctionnant en série comme dans t-sql, l'utilisation du processeur n'atteint jamais plus de 8% sur le serveur 16-core. Chacune des procédures spécifiques à l'entité ne dépend pas des autres, mais toutes les entités de cette journée sont complètes avant le jour suivant.Comment exécuter des sous-tâches dans un SQL Procédure en parallèle

Mon idée est d'avoir une procédure de gestion CLR et de commencer les procédures plus longues pour la journée qui tourne sur leurs propres threads, puis une fois que les rapides sont terminés, Thread.Join() les longs threads en attente de toutes les entités compléter pour ce jour avant de passer à la suivante. Ci-dessous est mon essai comme la chose la plus simple qui pourrait fonctionner pour un seul thread de travail, et l'appel de Start sur ce thread ne provoque pas l'appel de la méthode statique. J'ai mis un point d'arrêt dans la méthode HelloWorld et il n'est jamais touché.

J'ai essayé quelque chose de très similaire à cela dans une application console et je l'ai fait fonctionner comme si je l'appelais sur le même thread dans la ligne commentée au début de AsyncHelloWorld. Y a-t-il quelque chose à propos du threading dans les procédures SQL CLR qui est différent?

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

Avez-vous une erreur ou rien ne se passe? – Nate

+0

La méthode HelloWorld n'est jamais appelée. –

Répondre

6

Vous ne pouvez absolument pas faire cela. Un SqlPipe est très fortement lié au contexte du thread sur lequel vous avez été invoqué. Bien que vous puissiez, techniquement, lancer des threads à partir de SQLCRL, ces threads doivent effectuer toutes les interactions avec l'appelant à partir du thread d'origine. Mais même ainsi, le lancement de threads CLR à l'intérieur de l'environnement hébergé SQL est une très mauvaise idée (et je ne vais pas entrer dans les détails pourquoi) très Au lieu de cela, séparez votre logique en procédures qui peuvent être appelées en parallèle et invoquez ces procédures en parallèle depuis le client. Vous pouvez utiliser Asynchronous procedure execution comme un modèle de procédures de planification à lancer de manière asynchrone et l'activation par file d'attente prend en charge le parallélisme via le paramètre MAX_QUEUE_READERS.

Mais très probablement vos procédures n'ont pas besoin de parallélisme explicite. Les charges T-SQL qui peuvent bénéficier d'un parallélisme explicite contrôlé par l'utilisateur sont si rares que cela ne vaut pas la peine d'être mentionné (sans compter que tirer la sémantique transactionnelle à travers les tâches parallèles dépasse les simples mortels). T-SQL peut tirer parti du parallélisme des instructions internes pour traiter les données en parallèle, de sorte qu'il n'y a jamais besoin de parallélisme explicite.

Mieux vaut vous expliquer ce que vous faites En passant ici, et nous pouvons peut-être vous aider.

+0

Je récapitule les enregistrements d'audit dans une base de données de rapports pour prendre en charge l'interrogation "As Of" du système signalé. Le processus d'importation comporte deux phases principales, l'une extrait les nouveaux enregistrements d'audit non analysés du système source et l'autre calcule les récapitulatifs et les transforme en entités déclarables. –

+0

Cela ressemble à une saveur d'ETL. Avez-vous considéré SSIS? –

+0

J'ai mis à jour la description pour ajouter plus d'arrière-plan. Je n'ai aucune expérience avec SSIS, êtes-vous capable de démarrer plus d'une procédure et d'obtenir une notification quand elles sont faites, ainsi de déclencher le début du prochain groupe? –

Questions connexes