Non , il n'y a pas de documentation de Microsoft garantissant le comportement, il n'est donc pas garanti .
En outre, en supposant que l'article Simple Talk est correct et que l'opérateur physique de concaténation traite toujours les entrées dans l'ordre indiqué dans le plan (très probablement vrai), puis sans garantie que SQL Server générera toujours des plans qui gardent les mêmes l'ordre entre le texte de la requête et le plan de requête, vous n'êtes que légèrement mieux loti.
Nous pouvons cependant approfondir cette question. Si l'optimiseur de requête a pu réorganiser l'entrée d'opérateur de concaténation, il doit exister des lignes dans le DMV non documenté, sys.dm_exec_query_transformation_stats
correspondant à cette optimisation.
SELECT * FROM sys.dm_exec_query_transformation_stats
WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'
Sur SQL Server 2012 Enterprise Edition, cela produit 24 lignes. En ignorant les fausses correspondances pour les transformations liées aux constantes, il existe une transformation liée à l'opérateur physique de concaténation UNIAtoCON
(Union All to Concatenation). Ainsi, au niveau de l'opérateur physique, il apparaît qu'une fois qu'un opérateur de concaténation est sélectionné, il sera traité dans l'ordre de l'opérateur logique Union All dont il est dérivé.
En fait, ce n'est pas tout à fait vrai. Il existe des réécritures post-optimisation qui peuvent réorganiser les entrées vers un opérateur de concaténation physique une fois l'optimisation basée sur les coûts terminée. Un exemple se produit lorsque la concaténation est soumise à un objectif de ligne (il peut donc être important de lire d'abord à partir de l'entrée la moins chère). Voir UNION ALL
Optimisation par Paul White pour plus de détails.
Cette réécriture physique tardive était fonctionnelle jusqu'à SQL Server 2008 R2 inclus, mais une régression signifiait qu'elle ne s'appliquait plus à SQL Server 2012 et versions ultérieures. Un correctif a été publié qui rétablit cette réécriture pour SQL Server 2014 et versions ultérieures (pas 2012) avec les correctifs de l'optimiseur de requête activés (par exemple, l'indicateur de trace 4199).
Mais à propos de l'opérateur Logical Union All ( UNIA
)? Il y a une UNIAReorderInputs
transformation, qui peut réorganiser les entrées. Il existe également deux opérateurs physiques qui peuvent être utilisés pour implémenter une Union logique UNIAtoCON
et UNIAtoMERGE
(Union All to Merge Union).
Il apparaît donc que l'optimiseur de requête peut réorganiser les entrées pour a UNION ALL
; cependant, il ne semble pas s'agir d'une transformation courante (zéro utilisation de UNIAReorderInputs
sur les serveurs SQL que j'ai facilement accessible. Nous ne connaissons pas les circonstances qui pourraient faire que l'optimiseur soit utilisé UNIAReorderInputs
; bien qu'il soit certainement utilisé lorsqu'un guide de plan ou une utilisation L'indice de plan est utilisé pour forcer un plan généré à l'aide des entrées physiques réordonnées de l'objectif de ligne mentionnées ci-dessus.
Existe-t-il un moyen pour que le moteur traite plus d'une entrée à la fois?
L'opérateur physique de concaténation peut exister dans une section parallèle d'un plan. Avec quelques difficultés, j'ai pu produire un plan avec des concaténations parallèles en utilisant la requête suivante:
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)
Ainsi, au sens strict, l'opérateur de concaténation physique semble toujours traiter les entrées de manière cohérente (première en haut, seconde en bas); cependant, l'optimiseur peut changer l'ordre des entrées avant de choisir l'opérateur physique ou utiliser une union de fusion au lieu d'une concaténation.
Réponse du wiki communautaire :
Je ne sais pas si vous pouvez prouver que tout comportement observé est toujours garanti, d'une manière ou d'une autre, à moins que vous ne puissiez fabriquer un contre-exemple. En l'absence de cela, la manière de corriger l'ordre de retour des résultats est bien sûr d'ajouter un
ORDER BY
.Je ne sais pas s'il existe un "correctif", ou s'il existe un besoin pour un correctif, si vous pouvez démontrer que dans certains scénarios, les requêtes sont traitées dans un ordre différent.
L'absence de documentation officielle explicite me suggère que vous ne devriez pas en dépendre. C'est exactement le genre de chose avec laquelle les gens ont eu des ennuis
ORDER BY
dans une vue etGROUP BY
sansORDER BY
, il y a 8 ans, lorsque l'optimiseur de SQL Server 2005 a été publié.Avec toutes les nouvelles fonctionnalités des nouvelles versions de SQL Server (avec d'autres à venir), même si vous pensez pouvoir garantir un comportement spécifique aujourd'hui, je ne m'attendrais pas à ce qu'il se vérifie (jusqu'à ce qu'il soit documenté pour le faire).
Même si vous ne dépendez pas de ce comportement, qu'allez-vous faire des résultats? Quoi qu'il en soit, je n'appellerais pas un article Simple Talk par un officiel extérieur . Pour tout ce que nous savons, ce n'est qu'une supposition basée sur l'observation.
Microsoft ne publiera jamais de documentation officielle disant que «x» n'est pas garanti pour faire «y». C'est l'une des raisons pour lesquelles nous avons encore, près d'une décennie plus tard, des difficultés à convaincre les gens qu'ils ne peuvent pas se fier à la commande observée sans
ORDER BY
- il n'y a aucune documentation qui déclare "ce n'est pas garanti".la source