¿Es el soporte para Parallel Scalar UDF una solicitud de función razonable?

10

Está bastante bien documentado que los UDF escalares fuerzan un plan en serie general.

Ejecutando funciones en paralelo

Dada una gran cantidad de filas que llegan a un punto en la tubería donde se debe calcular un UDF, ¿por qué el motor no puede simplemente distribuirlas entre los procesadores? Si no hay estado dentro de un UDF, entonces el orden no debería importar.

Hay afirmaciones de que UDF es un cuadro negro que debe usar el cursor. Puedo ver que un cursor de usuario no se puede paralelizar dentro de un SP para los casos en que se mantiene algún estado entre iteraciones, pero parece que de lo contrario debería ser paralelo.

Puntos adicionales para explicar por qué el motor obliga a que todo el plan sea serial en lugar de solo la etapa de cálculo de UDF.

¿Es el soporte para UDF paralelo una característica razonable para solicitar?

crokusek
fuente
1
La reacción apropiada parece ser, como se señala en la respuesta aceptada a su enlace, reescribir cualquier función definida por el usuario escalar como una sola columna en línea con funciones con valores de tabla . Estos se expanden de la misma manera que una vista y, por lo tanto, están completamente optimizados. A la luz de esto, ¿su pregunta todavía tiene mérito?
Pieter Geerkens
1
Sí en caso de éxito con la solución de TVF. Le pregunté porque parece incorrecto evitar el uso de una construcción tan natural. También parece poco práctico esperar que los nuevos desarrolladores de SQL aprendan aspectos internos de UDF.
crokusek
Comentario aclaratorio Éxito con ITVF pero no con TVF multi-declaración.
crokusek

Respuestas:

17

Está bastante bien documentado que las UDF fuerzan un plan en serie general.

No estoy seguro de que esté tan bien documentado.

  • Una función escalar T-SQL evita el paralelismo en cualquier parte del plan.
  • Una función CLR escalar se puede ejecutar en paralelo, siempre que no acceda a la base de datos.
  • Una función T-SQL con valores de tabla de varias instrucciones fuerza una zona en serie en un plan que puede usar paralelismo en otro lugar.
  • Una función T-SQL en línea con valores de tabla se expande como una vista, por lo que no tiene efecto directo.

Consulte Forzar un plan de ejecución paralela y / o la presentación de ejecución paralela de Craig Freedman .

Hay reclamos acerca de que los UDF son un cuadro negro que debe usar el cursor.

Estas afirmaciones no son correctas.

Puntos adicionales para explicar por qué el motor obliga a que todo el plan sea serial en lugar de solo la etapa de cálculo de UDF.

Tengo entendido que las restricciones actuales son puramente el resultado de ciertos detalles de implementación. No hay una razón fundamental por la cual las funciones no puedan ejecutarse usando paralelismo.

Específicamente, las funciones escalares T-SQL se ejecutan dentro de un contexto T-SQL separado, lo que complica significativamente la operación correcta, la coordinación y el apagado (especialmente en el caso de un error).

Del mismo modo, las variables de tabla admiten lecturas paralelas (pero no escrituras) en general, pero la variable de tabla expuesta por una función con valores de tabla no puede admitir lecturas paralelas por razones específicas de implementación. Me temo que necesitaría a alguien con acceso al código fuente (y la libertad de compartir detalles) para proporcionar una respuesta autorizada.

¿Es el soporte para UDF paralelo una característica razonable para solicitar?

Por supuesto, si puedes hacer un caso lo suficientemente fuerte. Mi propio sentimiento es que el trabajo involucrado sería extenso, por lo que su propuesta tendría que alcanzar un nivel extremadamente alto. Por ejemplo, una solicitud relacionada (y mucho más simple) para proporcionar funciones escalares en línea tiene un gran soporte, pero ha languidecido sin implementarse durante años.


Es posible que desee leer el documento de Microsoft:

... que describe el enfoque que Microsoft adoptará para abordar los problemas de rendimiento de la función escalar T-SQL en la versión posterior a SQL Server 2017.

El objetivo de Froid es permitir a los desarrolladores utilizar las abstracciones de UDF y procedimientos sin comprometer el rendimiento. Froid logra este objetivo utilizando una técnica novedosa para convertir automáticamente programas imperativos en formas algebraicas relacionales equivalentes siempre que sea posible. Froid modela bloques de código imperativo como expresiones relacionales y los combina sistemáticamente en una sola expresión utilizando el operador Apply, lo que permite al optimizador de consultas elegir planes de consulta paralelos y orientados a conjuntos eficientes .

(énfasis mío)


Las funciones T-SQL escalares en línea ahora se implementan en SQL Server 2019 .

Paul White 9
fuente
11

Como Paul ha mencionado correctamente en su respuesta, no hay una razón fundamental por la que no se puedan ejecutar UDF escalares utilizando paralelismo. Sin embargo, aparte de los desafíos de implementación, hay otra razón para obligarlos a ser seriales. El documento de Froid citado por Paul da más información sobre esto.

Citando del artículo (Sección 2.3):

Actualmente, SQL Server no utiliza el paralelismo intraconsulta en consultas que invocan UDF. Los métodos pueden diseñarse para mitigar esta limitación, pero presentan desafíos adicionales, como elegir el grado correcto de paralelismo para cada invocación del UDF.

Por ejemplo, considere un UDF que invoca otras consultas SQL, como la de la Figura 1. Cada consulta puede usar paralelismo y, por lo tanto, el optimizador no tiene forma de saber cómo compartir hilos a través de ellas, a menos que examine el UDF y decide el grado de paralelismo para cada consulta dentro (lo que podría cambiar de una invocación a otra). Con UDF anidados y recursivos, este problema se vuelve aún más difícil de manejar.

El enfoque de Froid, como se describe en el documento, no solo dará como resultado planes paralelos, sino que también agregará muchos más beneficios para consultas con UDF. En esencia, subsume su solicitud de ejecución paralela de UDF.

Actualización: Froid ahora está disponible como una característica de la vista previa de SQL Server 2019. La característica se llama "Incrustación UDF escalar". Más detalles aquí: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/

[Divulgación: soy coautor del artículo de Froid]

Karthik
fuente
¡Muy bien! Si entiendo correctamente, va a convertir automáticamente el UDF en un ITVF internamente. Habíamos hecho esto por unos pocos (w / declares / if / else) e hicimos un buen desastre. Incluso tuvimos una "columna" de depuración.
crokusek
1
En realidad, no convierte el UDF en un ITVF, pero su intuición es correcta. Hacer esto manualmente en el nivel de consulta SQL es realmente complicado para las UDF complejas. Froid realiza esta transformación en el árbol de álgebra relacional, lo que evita el desorden :)
Karthik
@Karthik, ¿podrías echar un vistazo a dba.stackexchange.com/questions/202211/… . Realmente me gustaría saber cómo va a funcionar Froid en el caso descrito
Roman Pekar
@Roman He comentado tu pregunta.
Karthik
1
Gracias, @Karthik, por el trabajo que hizo en el documento de Froid, y en sus esfuerzos (y los de los grupos) para mejorar la usabilidad de los UDF escalares :-)
Solomon Rutzky