¿Hay ALGUNA forma de hacer que el resultado tenga exactamente 3 guías distintas y nada más? Espero poder responder mejor a las preguntas en el futuro al incluir guías de plan con consultas de tipo CTE a las que se hace referencia varias veces para superar algunas peculiaridades de SQL Server CTE.
Hoy no. Las expresiones de tabla común (CTE) no recursivas se tratan como definiciones de vista en línea y se expanden en el árbol de consulta lógica en cada lugar al que se hace referencia (al igual que las definiciones de vista regulares) antes de la optimización. El árbol lógico para su consulta es:
LogOp_OrderByCOL: Union1007 ASC COL: Union1015 ASC
LogOp_Project COL: Union1006 COL: Union1007 COL: Union1014 COL: Union1015
LogOp_Join
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
Observe los dos anclajes de vista y las seis llamadas a la función intrínseca newid
antes de que comience la optimización. Sin embargo, muchas personas consideran que el optimizador debería poder identificar que los subárboles expandidos eran originalmente un solo objeto referenciado y simplificar en consecuencia. También ha habido varias solicitudes de Connect para permitir la materialización explícita de una tabla CTE o derivada.
Una implementación más general haría que el optimizador considerara materializar expresiones comunes arbitrarias para mejorar el rendimiento ( CASE
con una subconsulta es otro ejemplo donde pueden ocurrir problemas hoy en día). Microsoft Research publicó un documento (PDF) sobre eso en 2007, aunque sigue sin implementarse hasta la fecha. Por el momento, estamos limitados a la materialización explícita usando cosas como variables de tabla y tablas temporales.
SQLKiwi ha mencionado la elaboración de planes en SSIS, ¿hay alguna forma o herramienta útil para ayudar a diseñar un buen plan para SQL Server?
Esto fue solo una ilusión de mi parte, y fue mucho más allá de la idea de modificar las guías del plan. Es posible, en principio, escribir una herramienta para manipular directamente el XML del plan de presentación, pero sin una instrumentación optimizadora específica, usar la herramienta probablemente sería una experiencia frustrante para el usuario (y el desarrollador piensa en ello).
En el contexto particular de esta pregunta, dicha herramienta aún sería incapaz de materializar el contenido de CTE de una manera que podría ser utilizada por múltiples consumidores (para alimentar ambas entradas a la unión cruzada en este caso). El optimizador y el motor de ejecución son compatibles con los carretes de múltiples consumidores, pero solo para fines específicos, ninguno de los cuales podría aplicarse a este ejemplo en particular.
Si bien no estoy seguro, tengo el presentimiento de que se puede seguir RelOps (Nested Loop, Lazy Spool) incluso si la consulta no es exactamente la misma que el plan, por ejemplo, si agregó 4 y 5 al CTE , sigue utilizando el mismo plan (aparentemente probado en SQL Server 2012 RTM Express).
Aquí hay una cantidad razonable de flexibilidad. La forma amplia del plan XML se utiliza para guiar la búsqueda de un plan final (aunque muchos atributos se ignoran por completo, por ejemplo, el tipo de partición en los intercambios) y las reglas de búsqueda normales también se relajan considerablemente. Por ejemplo, se desactiva la poda temprana de alternativas basadas en consideraciones de costos, se permite la introducción explícita de combinaciones cruzadas y se ignoran las operaciones escalares.
Hay demasiados detalles para profundizar, pero no se puede forzar la colocación de Filtros y Calcular escalares, y los predicados del formulario column = value
se generalizan para que un plan que contenga X = 1
o X = @X
se pueda aplicar a una consulta que contenga X = 502
o X = @Y
. Esta flexibilidad particular puede ayudar enormemente a encontrar un plan natural para forzar.
En el ejemplo específico, constante Union All siempre se puede implementar como una exploración constante; el número de entradas a la Unión Todos no importa.