2010-01-26 16 views
16

J'ai utilisé les procédures de stockage CLR dans le serveur SQL pendant un certain temps, mais je me demande toujours quelles sont les meilleures situations pour les utiliser. MSDN fournit quelques instructions pour une utilisation comme la manipulation de chaînes lourdes (regex) ou le remplacement de T-SQL qui déclare beaucoup de variables de table et de curseurs. Je suis curieux de savoir quels sont les problèmes que les utilisateurs de SO résolvent avec les procs stockés CLR, ainsi que les exemples/benchmarks. Par exemple, j'ai trouvé CLR stocké procs + SSRS pour être un excellent moyen de sortir la logique de manipulation de données de SSRS et hors de T-SQL, et dans le code managé qui est plus facile à lire et à manipuler.Quels sont les bons problèmes à résoudre à l'aide de procs stockés CLR?

Répondre

23

De nombreux problèmes nécessitant dénormalisation et/ou des opérations séquentielles peuvent être traitées exceptionnellement bien par le CLR et peut être utilisé pour améliorer considérablement les performances sans sacrifier la facilité d'utilisation à l'extrémité SQL (beaucoup). Au lieu de vous fier entièrement à des opérations basées sur des ensembles ou des opérations itératives, vous pouvez adopter une approche hybride, utiliser une solution basée sur un ensemble pour les grandes remontées et passer à un modèle itératif pour les boucles serrées.

Les types intégrés hierarchyid et géospatial (c'est-à-dire geography) dans SQL Server 2008 sont de bons exemples du problème de dénormalisation. Les deux contiennent une quantité (presque) arbitrairement importante de données qui sont difficiles à normaliser sans nuire aux performances - vous devez utiliser la récursivité ou les curseurs pour effectuer un travail significatif avec eux ou utiliser un ensemble de triggers et/ou de tâches planifiées maintenir une table de dénormalisation.

Un autre problème que j'ai résolu avec les types CLR est la compression en ligne. Cela peut sembler un exercice inutile ou académique, mais lorsque vos données entièrement normalisées poussent dans les téraoctets, une réduction de 80 à 90% de la taille signifie beaucoup. SQL a sa propre compression intégrée maintenant et SQL 2005 a vardecimal, et ce sont de bons outils, mais un algorithme de "minimisation" de domaine peut être plusieurs fois plus efficace en termes de charge CPU et de taux de compression. Évidemment, cela ne s'applique pas à tous les problèmes, mais cela s'applique à certains.

Encore un autre problème très commun souvent trouvé sur ce site est la génération d'une séquence à la volée - par exemple une séquence de dates consécutives.Les solutions courantes sont les CTE récursifs, les tables de séquences statiques et les tables spt_values peu connues, mais un simple UDF CLR fonctionne mieux que n'importe lequel d'entre eux et offre beaucoup plus de flexibilité.

Dernière sur ma liste: Les agrégats de flux définis par l'utilisateur sont également très utiles, en particulier pour tout ce qui concerne les statistiques. Il y a certaines choses que vous ne pouvez tout simplement pas composer à partir des agrégats SQL intégrés, tels que les médianes, les moyennes mobiles pondérées, etc. Les UDA peuvent également prendre plusieurs arguments afin de pouvoir les paramétrer; Techniquement, un agrégat n'est pas garanti pour recevoir des données dans un ordre particulier dans la version actuelle de SQL Server, mais vous pouvez contourner cette limitation en lui attribuant un ROW_NUMBER comme argument supplémentaire et l'utiliser pour implémenter à peu près n'importe quelle fonction de fenêtrage. l'agrégat crache un UDT qui peut ensuite être transformé en une table).

En fait, il est très frustrant de voir combien il y a d'exemples d'applications SQL-CLR vraiment utiles; recherche sur Google et vous obtiendrez 10 millions de résultats, chacun d'entre eux pour une chaîne de concaténation idiote ou regex. Ils sont utiles, mais prenez quelques minutes pour en savoir plus sur les UDT et les UDA SQL, et vous commencerez à voir beaucoup d'utilisations pour eux dans vos propres applications. Ne soyez pas fous, bien sûr - réfléchissez bien à la question de savoir s'il existe une meilleure solution en langage SQL pur - mais ne les évitez pas non plus.

+2

Ceci est l'un des messages les plus informatifs que j'ai jamais lu. Je vous remercie. –

+0

+1 très joliment mis –

5

Manipulation de chaînes - la recherche d'expression régulière est un classique. Très facile à exposer en CLR, très difficile à faire en T-SQL. Voir this link pour les détails de mise en œuvre et un micro-benchmark (SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF).

5

La manipulation de chaînes (regexes) a déjà été mentionnée, mais aussi l'arithmétique DateTime et, bien sûr, un autre service web externe biggie.

+0

Hey Marc, pouvez-vous donner un exemple d'un problème que vous résoudriez en accédant à des services web externes dans un processus CLR? +1 pour l'utilité à coup sûr. –

+0

Beaucoup de choses - par ex. obtenir les taux de change à jour, obtenir des informations boursières à jour et beaucoup plus –

2
  • agrégats personnalisés
  • manipulation de chaînes
  • types de données sur mesure

Pour être honnête, je ne vois que la gestion des chaînes qui comprend CSVs de division en lignes.

Je considérerais tout ce qui nécessite plus que le niveau de confiance par défaut pour être hors limites, à moins que je ne sois un administrateur de bases de données en train de faire du DBA.

De MSDN avec RegEx et RSS exemples RSS: Using CLR Integration in SQL Server 2005

3

Voici un exemple de quelque chose que j'utilisé procs CLR pour que je pensais était propre:

mises à jour de données chronométrées de webservices externes à l'aide procs stockées CLR et SQL emplois.

Nous avons une application qui synchronise certaines des données qu'il suit avec des flux de données externes à l'industrie. La synchronisation s'exécute toutes les semaines pour tout et à la demande pour les mises à jour simples. J'ai donc une API webservice existante pour y accéder. Les choses sont déjà programmées par un service windows mais je me suis dit pourquoi ne pas pouvoir les programmer comme nos autres jobs SQL?

J'ai créé une procédure stockée CLR qui réoriente l'API de service Web de l'application. Ensuite, j'ai ajouté quelques paramètres pour @RecordID pour prendre en charge la synchronisation unique et l'avoir planifié dans les travaux SQL d'Enterprise Manager.

Maintenant, je peux utiliser le Job pour exécuter des synchronisations dB ou utiliser le proc dans d'autres procs ou Triggers SQL pour mettre à jour les données du flux externe.

Il est peut-être plus simple de sortir l'API webservice d'application à l'avenir et d'utiliser directement le service Web externe. Pour l'instant cependant, cela a été très rapide à implémenter et une manière cool d'étendre les fonctionnalités au groupe SQL.

1

Il est très utile d'extraire des données d'un système qui ne fournit pas d'interface SQL traditionnelle ou dont l'implémentation par le fournisseur est inférieure à la normale.

Nous avons une application principale basée sur l'ancienne plate-forme MUMPS, exécutée sur la base de données Intersystems Cache. Les données sont hiérarchiques et non relationnelles. Le tableau global principal (c'est-à-dire la table) a plusieurs niveaux de données et tous les éléments sont regroupés par numéro de compte. L'analyse d'une seule colonne nécessite que le global soit chargé à partir du disque et cela prend 8+ heures. Le fournisseur fournit un pilote ODBC et des mappages aux globals, mais il en résulte souvent un balayage et des requêtes extrêmement lentes.

J'ai construit une fonction de valeur de table qui prend un programme ObjectScript (Intersystem du dialecte de MUMPS), l'exécute sur le serveur Cache et retourne les lignes de sortie sous forme de lignes de données. Je peux microgérer le chemin d'accès aux données du côté MUMPS (c'est vraiment ce qu'il faut pour obtenir un accès aux données efficace) en fournissant un programme spécifique à exécuter de ce côté, puis importer facilement les données dans MSSQL comme source de données ad-hoc.

Je peux utiliser le TVF pour piloter la sélection de données ou utiliser CROSS APPLY pour effectuer des recherches à l'autre extrémité et c'est raisonnablement efficace. Je peux même exécuter plusieurs requêtes sur l'extrémité distante en parallèle si je force MSSQL à utiliser un plan d'exécution parallèle.

+0

> "et renvoie les lignes de sortie en tant que lignes de données." Avez-vous mis les données dans un System.Data.DataTable en premier? J'ai quelques fonctions d'aide pour écrire des tables de données mais je me demande comment cela pourrait être fait avec un IEnumerable par exemple. – tbone

+0

Il existe une méthode FillRow avec la fonction Table Valued en continu, qui a une projection fixe de lignes. Dans la version originale, j'ai renvoyé jusqu'à 8 champs de caractères de la requête comme F1, F2, F3 ... –

+0

Merci - exemple pertinent je pense: http://stackoverflow.com/questions/6901811/sql-clr-streaming- table-évalué-fonction-résultats – tbone