Operación física de concatenación: ¿garantiza el orden de ejecución?

12

En SQL estándar, union allno se garantiza que el resultado de a esté en ningún orden. Entonces, algo como:

select 'A' as c union all select 'B'

Podría devolver dos filas en cualquier orden (aunque, en la práctica, en cualquier base de datos que conozco, 'A' vendrá antes que 'B').

En SQL Server, esto se convierte en un plan de ejecución utilizando una operación física de "concatenación".

Me podría imaginar fácilmente que la operación de concatenación escanearía sus entradas, devolviendo cualquier entrada que tenga registros disponibles. Sin embargo, encontré la siguiente declaración en la web ( aquí ):

El procesador de consultas ejecutará este plan en el orden en que aparecen los operadores en el plan, el primero es el superior y el último es el final.

Pregunta: ¿Es esto cierto en la práctica? ¿Se garantiza que esto sea cierto?

No he encontrado ninguna referencia en la documentación de Microsoft de que las entradas se escaneen en orden, de la primera a la última. Por otro lado, cada vez que intento ejecutarlo, los resultados sugieren que las entradas, de hecho, se procesan en orden.

¿Hay alguna manera de que el motor procese más de una entrada a la vez? Mis pruebas (que usan expresiones mucho más complicadas que las constantes) se realizan en una máquina de 8 núcleos habilitada en paralelo, y la mayoría de las consultas aprovechan el paralelismo.

Gordon Linoff
fuente

Respuestas:

10

No , no hay documentación de Microsoft que garantice el comportamiento, por lo tanto, no está garantizado .

Además, suponiendo que el artículo de Simple Talk sea correcto y que el operador físico de Concatenación siempre procese las entradas en el orden que se muestra en el plan (muy probablemente sea cierto), sin una garantía de que SQL Server siempre generará planes que mantengan el mismo el orden entre el texto de la consulta y el plan de consulta, solo está un poco mejor.

Sin embargo, podemos investigar esto más a fondo. Si el optimizador de consultas pudo reordenar la entrada del operador de Concatenación, deberían existir filas en el DMV no documentado, sys.dm_exec_query_transformation_statscorrespondientes a esa optimización.

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

En SQL Server 2012 Enterprise Edition, esto produce 24 filas. Ignorando las coincidencias falsas para las transformaciones relacionadas con las constantes, hay una transformación relacionada con el Operador físico de concatenación UNIAtoCON(Union All to Concatenation). Por lo tanto, en el nivel del operador físico, parece que una vez que se selecciona un operador de concatenación, se procesará en el orden del operador lógico Union All del que se deriva.


De hecho, eso no es del todo cierto. Existen reescrituras posteriores a la optimización que pueden reordenar las entradas a un operador físico de Concatenación después de que se haya completado la optimización basada en costos. Un ejemplo ocurre cuando la Concatenación está sujeta a un objetivo de fila (por lo que puede ser importante leer primero la entrada más barata). Vea UNION ALLOptimización por Paul White para más detalles.

Esa reescritura física tardía fue funcional hasta SQL Server 2008 R2 incluido, pero una regresión significaba que ya no se aplicaba a SQL Server 2012 y posteriores. Se ha emitido una corrección que restablece esta reescritura para SQL Server 2014 y posterior (no 2012) con las revisiones del optimizador de consultas habilitadas (por ejemplo, el indicador de seguimiento 4199).


¿Pero sobre el operador Logical Union All ( UNIA)? Hay una UNIAReorderInputstransformación que puede reordenar las entradas. También hay dos operadores físicos que se pueden usar para implementar un Union All lógico UNIAtoCONy UNIAtoMERGE(Union All para combinar Union).

Por lo tanto, parece que el optimizador de consultas puede reordenar las entradas para a UNION ALL; sin embargo, no parece ser una transformación común (cero usos de UNIAReorderInputslos Servidores SQL a los que tengo acceso fácilmente. No sabemos las circunstancias que harían que el optimizador use UNIAReorderInputs; aunque ciertamente se usa cuando una guía de plan o uso La sugerencia de plan se utiliza para forzar un plan generado utilizando las entradas físicas reordenadas del objetivo de fila mencionadas anteriormente.

¿Hay alguna manera de que el motor procese más de una entrada a la vez?

El operador físico de concatenación puede existir dentro de una sección paralela de un plan. Con cierta dificultad, pude producir un plan con concatenaciones paralelas usando la siguiente consulta:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Por lo tanto, en el sentido más estricto, el operador de Concatenación física siempre parece procesar las entradas de manera coherente (el primero primero, el segundo inferior); sin embargo, el optimizador podría cambiar el orden de las entradas antes de elegir el operador físico, o usar una unión Merge en lugar de una Concatenación.

StrayCatDBA
fuente
8

Según Craig Freedman, el orden de ejecución para el operador de concatenación está garantizado.

De su publicación de blog Visualización de planes de consulta en blogs de MSDN:

Tenga en cuenta que cuando un operador tiene más de un hijo, el orden de los hijos es importante. El hijo superior es el primer hijo, mientras que el hijo inferior es el segundo. El operador de concatenación procesa los elementos secundarios en este orden.

Y de los libros en línea Showplan Referencia de operadores lógicos y físicos

El operador físico de concatenación tiene dos o más entradas y una salida. La concatenación copia filas de la primera secuencia de entrada a la secuencia de salida, luego repite esta operación para cada secuencia de entrada adicional.

Mikael Eriksson
fuente
Esa cita está bastante cerca de lo que estaba buscando. Estoy dispuesto a dar el salto de ser ejecutado en ese orden para ser devuelto en ese orden, aunque es decepcionante que la documentación impida el procesamiento paralelo en este caso.
Gordon Linoff
2

Respuesta wiki comunitaria :

No sé si puede probar que cualquier comportamiento observado siempre está garantizado, de una forma u otra, a menos que pueda fabricar un contraejemplo. En ausencia de eso, la forma de arreglar el orden en que se devuelven los resultados, por supuesto, es agregar un ORDER BY.

No sé si hay una "solución", o si existe la necesidad de una solución, si puede demostrar que en algunos escenarios las consultas se procesan en un orden diferente.

La falta de documentación oficial explícita me sugiere que no debe depender de esto. Este es exactamente el tipo de cosa que la gente tiene problemas con ORDER BYen una vista, y GROUP BYsin ORDER BYhace 8 años, cuando optimizador de SQL Server 2005 fue puesto en libertad.

Con todas las nuevas características en las versiones más recientes de SQL Server (con más por venir), incluso si cree que puede garantizar un comportamiento específico hoy, no esperaría que sea cierto (hasta que se documente para hacerlo).

Incluso si no depende de este comportamiento, ¿qué va a hacer con los resultados? De todos modos, no llamaría a un artículo de Simple Talk de un funcionario externo . Por lo que sabemos, esto es solo una suposición basada en la observación.

Microsoft nunca publicará documentación oficial que diga que 'x' no garantiza que haga 'y'. Esta es una de las razones por las que todavía, casi una década después, tenemos problemas para convencer a las personas de que no pueden confiar en los pedidos observados sin ellos ORDER BY: no hay documentación que diga "no está garantizado".

revs usuario126897
fuente