Je comprends que vous ne pouvez pas avoir ORDER BY
dans une vue. (Au moins dans SQL Server 2012, je travaille avec)
Je comprends également que la manière "correcte" de trier une vue consiste à placer une déclaration ORDER BY
autour de la SELECT
requête.
Mais étant relativement nouveau au SQL pratique et aux usages des vues, je voudrais comprendre pourquoi cela est fait par la conception. Si j'ai bien suivi l'historique, cela était autrefois possible et a été explicitement supprimé de SQL Server 2008, etc. (ne me citez pas sur la version exacte).
Cependant, la meilleure raison pour laquelle Microsoft peut supprimer cette fonctionnalité est "une vue est une collection non triée de données".
Je suppose qu'il existe une bonne raison logique pour laquelle une vue devrait être non triée. Pourquoi une vue ne peut-elle pas être simplement une collection de données aplatie? Pourquoi spécifiquement non trié? Il ne semble pas si difficile de trouver des situations dans lesquelles (du moins pour moi / IMHO) il semble parfaitement intuitif d’avoir une vue triée.
la source
Réponses:
(Vues indexées de côté, bien sûr.)
Une vue n'est pas matérialisée - les données ne sont pas stockées, alors comment pourrait-on les trier? Une vue est un peu comme une procédure stockée qui contient simplement un
SELECT
sans paramètre ... elle ne contient pas de données, elle ne contient que la définition de la requête. Etant donné que différentes références à la vue peuvent nécessiter des données triées de différentes manières, vous procédez ainsi - comme pour une sélection dans une table, qui correspond également à une collection non rangée de lignes - consiste à inclure la commande by dans la requête externe. .Également pour donner un petit aperçu de l'histoire. Vous ne pourriez jamais mettre
ORDER BY
en vue, sans aussi inclureTOP
. Et dans ce cas, il a étéORDER BY
dicté quelles lignes étaient incluses parTOP
, pas comment elles seraient présentées. Il se trouve que dans SQL Server 2000, siTOP
était100 PERCENT
ou{some number >= number of rows in the table}
, l’optimiseur était assez simpliste et il a fini par produire un plan avec une sorte qui correspond à laTOP/ORDER BY
. Mais ce comportement n'a jamais été garanti ni documenté - il a simplement été basé sur l'observation, ce qui est une mauvaise habitude . Lorsque SQL Server 2005 est sorti, ce problème a commencé à se "rompre" en raison de changements dans l'optimiseur qui ont conduit à l'utilisation de plans et d'opérateurs différents - entre autres choses, leTOP / ORDER BY
serait complètement ignoré si c'était le casTOP 100 PERCENT
. Certains clients se sont plaints de cela si fort que Microsoft a émis un indicateur de trace pour rétablir l'ancien comportement. Je ne vais pas vous dire ce qu'est le drapeau car je ne veux pas que vous l'utilisiez et je veux m'assurer que l'intention est correcte - si vous voulez un ordre de tri prévisible, utilisez-ORDER BY
le dans la requête externe.Pour résumer et clarifier tout autant ce que vous avez dit: Microsoft n’a rien supprimé . Ils ont amélioré le produit et, par conséquence, ce comportement non documenté et non garanti est devenu moins fiable. Globalement, je pense que le produit est meilleur pour cela.
la source
TOP
curseur effectue une opération sur le jeu de résultats. Par conséquent, il peut avoir un ordre explicite.TOP 100 PERCENT / ORDER BY
et le supprime complètement du plan. Essaye le.Si une vue pouvait être triée alors quel devrait être l'ordre du résultat ici?
la source
Une possibilité consiste à éviter les tris en conflit: si la vue trie selon un ordre et que la sélection de cette vue trie selon un autre ordre (sans tenir compte du tri de la vue), il peut y avoir un impact négatif sur les performances. Il est donc plus sûr de laisser l’exigence de tri à l’utilisateur.
Autre raison, le tri entraîne un coût en termes de performances. Pourquoi pénaliser tous les utilisateurs de la vue alors que seuls certains utilisateurs en ont besoin?
la source
ANSI SQL n'autorise la
ORDER BY
requête la plus externe que pour une variété de raisons, l'une d'entre elles étant ce qui se produit lorsqu'une sous-sélection / vue / CTE est jointe à une autre table et que la requête externe estORDER BY
elle-même.Le serveur SQL ne l'a jamais supporté dans une vue (à moins que vous l'ayez trompée en utilisant un
TOP 100 PERCENT
qui, à mon avis, provoque généralement un bogue).Même si vous avez déclenché le bogue, les résultats n'ont jamais été fiables et le tri ne s'est pas toujours déroulé comme prévu.
Consultez ce billet de blog de l'équipe Query Optimizer pour une explication technique complète. TOP 100 pour cent ORDER BY Considered Harmful.
la source
Les vues se comportent comme des tables dont le contenu est déterminé par les résultats d'une requête.
Les tables n'ont pas d'ordre; ce ne sont que des sacs de rangées.
Par conséquent, les vues ne sont pas en ordre non plus. Vous pouvez cependant les trier en sélectionnant des lignes dans un ORDER particulier.
la source
Une réponse qui n’a pas encore été donnée est que "ordre par" peut interférer avec la poussée des prédicats, ce qui peut grandement affecter les performances.
Un exemple est d'avoir une vue qui regroupe un grand ensemble de données dans un résumé de 10 lignes qui est top 10 / Ordered:
Pour le même cas avec un prédicat fort:
Cela prend toujours le même temps car top / order by empêche le prédicat d'être exécuté plus tôt dans le pipeline. Cela peut entraîner le traitement de lignes inutiles et le plan sera similaire à celui sans prédicat.
Si le push doit avoir lieu avant la commande par est vraiment un choix de développeur et peut changer la réponse. Le plus souvent, le push est l'intention logique.
L'utilisation logique de "100% supérieurs" permet logiquement de pousser les prédicats, mais l'implémentation ignore malheureusement "ordre par" pour ce cas et annule l'intention.
Pour les cas d'utilisation réels, un bon compromis serait que le moteur effectue "l'ordre en tirant". Cela permettrait de spécifier un "ordre de" dans la vue (avec 100% ou aucun sommet) et cet ordre n'est utilisé que si la vue est sélectionnée directement, sans ordre explicite, sans jointure, sans agrégat, sans voir chaînage, etc. Les deux cas énumérés ci-dessus pourraient être pris en charge par ce modèle simple.
la source
vous pouvez créer une vue qui a ordre et conserve l'ordre lorsqu'il est interrogé après:
sélectionnez en haut 99,999999999999 pour cent * de ..... trier par
la source
SELECT TOP 100 PERCENT ...
?