2010-01-26 27 views
16

He utilizado los procedimientos de almacenamiento de CLR en SQL Server por un tiempo, pero todavía me pregunto cuáles son las mejores situaciones para usarlos.¿Cuáles son los buenos problemas para resolver con los procesos almacenados CLR?

MSDN proporciona algunas pautas para el uso, como la manipulación de cadenas pesadas (regex), o el reemplazo de T-SQL que declara muchas variables de tabla y cursores. Tengo curiosidad por saber qué problemas están resolviendo los usuarios de SO con los procesos almacenados de CLR, y ejemplos/puntos de referencia también.

Por ejemplo, he encontrado que los procesos almacenados CLR + SSRS son una excelente manera de sacar la lógica de manipulación de datos de SSRS y fuera de T-SQL, y en el código administrado que es más fácil de leer y manipular.

Respuesta

23

Muchos de los problemas que requieren desnormalización y/o operaciones secuenciales pueden ser manejados excepcionalmente bien por el CLR y se pueden utilizar para mejorar drásticamente el rendimiento sin sacrificar la facilidad de uso en el extremo de SQL (mucho). En lugar de confiar por completo en operaciones iterativas o basadas en conjuntos, puede adoptar un enfoque híbrido, utilizar una solución basada en conjuntos para los grandes traslados y cambiar a un modelo iterativo para los bucles ajustados.

Los tipos incorporados hierarchyid y geoespaciales (es decir, geography) en SQL Server 2008 son buenos ejemplos del problema de desnormalización. Ambos contienen una cantidad (casi) arbitrariamente grande de datos que son difíciles de normalizar sin perjudicar el rendimiento. Tendría que usar recursion o cursores para hacer un trabajo significativo con ellos de lo contrario, o usar un nido de desencadenantes y/o tareas programadas para mantener una tabla de desnormalización

Otro problema que he resuelto con los tipos de CLR es la compresión en línea. Esto puede sonar como un ejercicio sin sentido o académico, pero cuando sus datos completamente normalizados están presionando en los terabytes, una reducción del 80-90% en el tamaño significa mucho. SQL tiene su propia compresión incorporada ahora y SQL 2005 tenía vardecimal, y esas son también buenas herramientas, pero un algoritmo de "minimización" de dominio puede ser varias veces más eficiente en términos de carga de CPU y tasa de compresión. Obviamente, esto no se aplica a todos los problemas, pero se aplica a algunos.

Otro problema muy común que a menudo se encuentra en este sitio es generar una secuencia sobre la marcha, por ejemplo, una secuencia de fechas consecutivas.Las soluciones comunes son los CTE recursivos, las tablas de secuencias estáticas y las poco conocidas tablas spt_values, pero un CLR UDF simple funciona mejor que cualquiera de ellos y ofrece mucha más flexibilidad.

Último en mi lista: los agregados de transmisión definidos por el usuario también son muy útiles, especialmente para cualquier cosa relacionada con las estadísticas. Hay algunas cosas que simplemente no puede componer a partir de los agregados de SQL incorporados, como medianas, promedios móviles ponderados, etc. Los ADU también pueden tomar múltiples argumentos para que pueda parametrizarlos; técnicamente no se garantiza que un agregado reciba datos en un orden particular en la versión actual de SQL Server, pero puede evitar esa limitación al alimentarlo con un ROW_NUMBER como argumento adicional y usarlo para implementar casi cualquier función de ventana (tener el agregado escupe un UDT que luego puede transformarse en una tabla).

En realidad, es muy frustrante la poca cantidad de ejemplos de aplicaciones verdaderamente útiles de SQL-CLR; busca en Google y obtienes 10 millones de resultados, cada uno de ellos por alguna concatenación de cadenas tontas o expresiones regulares. Estos son útiles, pero tómese unos minutos para aprender sobre los UDT y los UDA SQL en particular, y comenzará a ver muchos usos para ellos en sus propias aplicaciones. No se vuelvan locos, por supuesto, piensen cuidadosamente si existe o no una mejor solución en SQL puro, pero tampoco los descarten.

+2

Esta es una de las publicaciones más informativas que he leído en mi vida. Gracias. –

+0

+1 muy bien puso –

5

Manipulación de cadenas: la búsqueda de expresiones regulares es un clásico. Muy fácil de exponer en CLR, muy difícil de hacer en T-SQL directo.

Consulte this link para obtener detalles sobre la implementación y una micro-referencia (SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF).

5

Ya se mencionó la manipulación de cadenas (expresiones regulares), pero también la aritmética DateTime y, por supuesto, otros servicios web externos más llamativos.

+0

Hola Marc, ¿puedes dar un ejemplo de un problema que resolverías mediante el acceso a servicios web externos en un proceso CLR? +1 para la utilidad de seguro. –

+0

Muchas cosas, p. Ej. obtener las tasas de cambio de divisas actualizadas, obtener información actualizada de las acciones y mucho más –

2
  • personalizada agrega
  • manipulación de cadenas
  • tipos de datos personalizados

Para ser honesto, sólo veo manejo de cadenas CSV que incluye la división en las filas.

Consideraría todo lo que necesita más que el nivel de confianza predeterminado fuera de los límites, a menos que fuera un DBA haciendo cosas de tipo DBA.

De MSDN con expresiones regulares y en RSS ejemplos: Using CLR Integration in SQL Server 2005

3

Aquí es un ejemplo de algo que yo solía procsos CLR para que pensé que era ordenada:

actualizaciones de datos de servicios web externos temporizadas utilizando procs almacenado CLR y trabajos de SQL.

Tenemos una aplicación que sincroniza algunos de los datos que rastrea con fuentes de datos externas de la industria. La sincronización se ejecuta semanalmente para todo y también para actualizaciones individuales, así que tenía una API de servicio web existente para acceder a ella. Las cosas ya están programadas por un servicio de Windows, pero pensé ¿por qué no poder programarlas como nuestros otros trabajos de SQL?

Creé un procedimiento almacenado CLR que refiere la API del servicio web de la aplicación. Luego agregué algunos parms para @RecordID para admitir la sincronización simple, y lo programé en trabajos de Enterprise manager SQL.

Ahora puedo usar el trabajo para ejecutar las sincronizaciones de dB o utilizar el proceso en otros procesos de SQL o desencadenantes para actualizar los datos de la fuente de información externa.

Puede ser más limpio sacar la API del servicio web de la aplicación en el futuro y simplemente usar el servicio web externo directamente. Sin embargo, por ahora, esto fue muy rápido de implementar y una forma genial de extender la funcionalidad al grupo SQL.

1

Es muy útil para extraer datos de un sistema que no proporciona una interfaz SQL tradicional o la implementación del proveedor de esa interfaz es inferior a la normal.

Tenemos una aplicación principal basada en la plataforma MUMPS antigua, que se ejecuta en la base de datos de Intersystems Cache. La información es jerárquica, no de naturaleza relacional. La matriz global principal (es decir, la tabla) tiene múltiples niveles de datos y elementos, todos agrupados por número de cuenta. Escanear incluso una columna requiere que todo el global se cargue desde el disco y demora más de 8 horas. El proveedor proporciona un controlador ODBC y asignaciones a los globales, pero a menudo resulta en escaneo y consultas extremadamente lentas.

Creé una función con valores de tabla que toma un programa ObjectScript (dialecto del Intersystem de MUMPS), lo ejecuta en el servidor de caché y devuelve las líneas de salida como filas de datos. Puedo microgestionar la ruta de acceso a los datos en el lado de MOMPS (eso es realmente lo que se necesita para obtener acceso eficiente a los datos) al proporcionar un programa específico para ejecutar en ese lado y luego importar fácilmente los datos en MSSQL como una fuente de datos en línea ad-hoc.

Puedo usar TVF para manejar la selección de datos o usar CROSS APPLY para realizar búsquedas en el otro extremo y es bastante eficiente. Incluso puedo ejecutar múltiples consultas en el extremo remoto en paralelo si obligo a MSSQL a usar un plan de ejecución paralelo.

+0

> "y devuelve las líneas de salida como filas de datos." ¿Pusiste los datos en un System.Data.DataTable primero? Tengo algunas funciones auxiliares para escribir tablas de datos, pero me pregunto cómo se podría hacer con un IEnumerable, por ejemplo. – tbone

+0

Hay un método FillRow con la función de transmisión de valores de tabla, que tiene una proyección fija de filas. En la versión original, devolví hasta 8 campos de caracteres de la consulta como F1, F2, F3 ... –

+0

Gracias - ejemplo relevante, creo que: http://stackoverflow.com/questions/6901811/sql-clr-streaming- table-valued-function-results – tbone

Cuestiones relacionadas