No SQL padrão, union all
não é garantido que o resultado de a esteja em qualquer ordem. Então, algo como:
select 'A' as c union all select 'B'
Poderia retornar duas linhas em qualquer ordem (embora, na prática, em qualquer banco de dados que eu conheça, 'A' virá antes de 'B').
No SQL Server, isso se transforma em um plano de execução usando uma operação física de "concatenação".
Eu poderia facilmente imaginar que a operação de concatenação varreria suas entradas, retornando qualquer entrada que tivesse registros disponíveis. No entanto, encontrei a seguinte declaração na web ( aqui ):
O Processador de Consultas executará este plano na ordem em que os operadores aparecem no plano, o primeiro é o superior e o último é o final.
Pergunta: Isso é verdade na prática? Isso é garantido para ser verdade?
Não encontrei nenhuma referência na documentação da Microsoft de que as entradas são verificadas em ordem, da primeira à última. Por outro lado, sempre que tento executá-lo, os resultados sugerem que as entradas são, de fato, processadas em ordem.
Existe uma maneira de fazer com que o mecanismo processe mais de uma entrada por vez? Meus testes (usando expressões muito mais complicadas do que constantes) estão em uma máquina de 8 núcleos habilitada para paralelo, e a maioria das consultas tira proveito do paralelismo.
Não , não há documentação da Microsoft que garanta o comportamento, portanto não é garantido .
Além disso, supondo que o artigo Simple Talk esteja correto e que o operador físico Concatenation sempre processe as entradas na ordem mostrada no plano (muito provável que seja verdade), sem garantia de que o SQL Server sempre gerará planos que mantêm o mesmo a ordem entre o texto da consulta e o plano de consulta, você está apenas um pouco melhor.
Podemos investigar isso ainda mais. Se o otimizador de consulta conseguiu reordenar a entrada do operador Concatenação, deve haver linhas no DMV não documentado,
sys.dm_exec_query_transformation_stats
correspondentes a essa otimização.No SQL Server 2012 Enterprise Edition, isso produz 24 linhas. Ignorando as falsas correspondências para transformações relacionadas a constantes, existe uma transformação relacionada ao Operador Físico de Concatenação
UNIAtoCON
(Union All to Concatenation). Portanto, no nível do operador físico, parece que uma vez que um operador de concatenação é selecionado, ele será processado na ordem do operador lógico Union All do qual foi derivado.Na verdade, isso não é bem verdade. Existem reescritas pós-otimização que podem reordenar as entradas para um operador de concatenação físico após a conclusão da otimização baseada em custo. Um exemplo ocorre quando a concatenação está sujeita a uma meta de linha (portanto, pode ser importante ler primeiro a partir da entrada mais barata). Veja
UNION ALL
Otimização de Paul White para mais detalhes.Essa reescrita física tardia era funcional até e incluindo o SQL Server 2008 R2, mas uma regressão significava que ela não se aplicava mais ao SQL Server 2012 e posterior. Foi emitida uma correção que restabelece essa regravação para SQL Server 2014 e posterior (não 2012) com hotfixes do otimizador de consulta ativados (por exemplo, sinalizador de rastreamento 4199).
Mas sobre o operador Logical Union All (
UNIA
)? Há umaUNIAReorderInputs
transformação, que pode reordenar as entradas. Há também dois operadores físicos que podem ser usados para implementar um Union All lógicoUNIAtoCON
eUNIAtoMERGE
(Union All to Merge Union).Portanto, parece que o otimizador de consulta pode reordenar as entradas para um
UNION ALL
; no entanto, não parece ser uma transformação comum (zero uso deUNIAReorderInputs
nos SQL Servers que tenho prontamente acessíveis. Não sabemos as circunstâncias que fariam o uso do otimizadorUNIAReorderInputs
; embora certamente seja usado quando um guia de plano ou uso a dica de plano é usada para forçar um plano gerado usando as entradas reordenadas físicas de meta de linha mencionadas acima.O operador físico Concatenação pode existir em uma seção paralela de um plano. Com alguma dificuldade, consegui produzir um plano com concatenações paralelas usando a seguinte consulta:
Portanto, no sentido mais estrito, o operador físico de concatenação parece sempre processar as entradas de maneira consistente (primeiro a primeira, segunda inferior); no entanto, o otimizador pode alternar a ordem das entradas antes de escolher o operador físico ou usar uma união de mesclagem em vez de uma concatenação.
Segundo Craig Freedman , a ordem de execução do operador de concatenação é garantida.
De sua postagem no blog Viewing Query Plans on MSDN Blogs:
E dos livros online Showplan Logical and Physical Operators Reference
Resposta da wiki da comunidade :
Não sei se você pode provar que qualquer comportamento observado é sempre garantido, de uma forma ou de outra, a menos que você possa fabricar um contra-exemplo. Na ausência disso, a maneira de corrigir a ordem em que os resultados são retornados, é claro, é adicionar um arquivo
ORDER BY
.Não sei se existe um "conserto", ou se existe a necessidade de um conserto, se puder demonstrar que em alguns cenários as consultas são processadas em uma ordem diferente.
A falta de qualquer documentação oficial explícita sugere-me que você não deve depender disso. Esse é exatamente o tipo de coisa que causava problemas às pessoas com
ORDER BY
uma exibição eGROUP BY
semORDER BY
, 8 anos atrás, quando o otimizador do SQL Server 2005 foi lançado.Com todos os novos recursos nas versões mais recentes do SQL Server (com mais por vir), mesmo que você pense que pode garantir um comportamento específico hoje, eu não esperaria que isso fosse verdade (até que seja documentado).
Mesmo que você não dependa desse comportamento, o que fará com os resultados? De qualquer forma, eu não chamaria um artigo do Simple Talk de um oficial de fora . Pelo que sabemos, isso é apenas um palpite baseado na observação.
A Microsoft nunca publicará documentação oficial dizendo que 'x' não tem garantia de fazer 'y'. Esta é uma das razões pelas quais ainda, quase uma década depois, temos dificuldade em convencer as pessoas de que elas não podem confiar em pedidos observados sem
ORDER BY
- não há documentação que afirme "não é garantido".