Une vue est-elle plus rapide qu'une simple requête?


359

Est un

select *  from myView

plus rapide que la requête elle-même pour créer la vue (afin d'avoir le même résultat):

select * from ([query to create same resultSet as myView])

?

Il n'est pas totalement clair pour moi si la vue utilise une sorte de mise en cache, ce qui la rend plus rapide par rapport à une simple requête.


7
Je ne suis pas sûr d'une vue, mais les vues imbriquées sont un enfer de performance totale.
Muflix

Réponses:


680

Oui , les vues peuvent avoir un index cluster affecté et, lorsqu'elles le font, elles stockent des résultats temporaires qui peuvent accélérer les requêtes résultantes.

Mise à jour: au moins trois personnes m'ont voté contre celui-ci. Avec tout le respect que je vous dois, je pense qu'ils ont tout simplement tort; La propre documentation de Microsoft indique très clairement que Views peut améliorer les performances.

Premièrement, les vues simples sont développées sur place et ne contribuent donc pas directement à l'amélioration des performances - c'est vrai. Cependant, les vues indexées peuvent considérablement améliorer les performances.

Permettez-moi d'aller directement à la documentation:

Une fois qu'un index cluster unique est créé sur la vue, le jeu de résultats de la vue est immédiatement matérialisé et persiste dans le stockage physique dans la base de données, ce qui évite de surcharger l'exécution de cette opération coûteuse au moment de l'exécution.

Deuxièmement, ces vues indexées peuvent fonctionner même lorsqu'elles ne sont pas directement référencées par une autre requête, car l'optimiseur les utilisera à la place d'une référence de table le cas échéant.

Encore une fois, la documentation:

La vue indexée peut être utilisée dans une exécution de requête de deux manières. La requête peut référencer directement la vue indexée ou, plus important encore, l'optimiseur de requête peut sélectionner la vue s'il détermine que la vue peut être remplacée par une partie ou la totalité de la requête dans le plan de requête le moins cher. Dans le second cas, la vue indexée est utilisée à la place des tables sous-jacentes et de leurs index ordinaires. La vue n'a pas besoin d'être référencée dans la requête pour que l'optimiseur de requête l'utilise pendant l'exécution de la requête. Cela permet aux applications existantes de bénéficier des vues indexées nouvellement créées sans modifier ces applications.

Cette documentation, ainsi que des graphiques illustrant les améliorations des performances, sont disponibles ici .

Mise à jour 2: la réponse a été critiquée sur la base que c'est l '"index" qui fournit l'avantage de performance, pas le "View". Cependant, cela est facilement réfuté.

Disons que nous sommes une entreprise de logiciels dans un petit pays; Je vais utiliser la Lituanie comme exemple. Nous vendons des logiciels dans le monde entier et conservons nos enregistrements dans une base de données SQL Server. Nous avons beaucoup de succès et donc, dans quelques années, nous avons plus de 1 000 000 d'enregistrements. Cependant, nous devons souvent déclarer des ventes à des fins fiscales et nous constatons que nous n'avons vendu que 100 copies de nos logiciels dans notre pays d'origine. En créant une vue indexée uniquement des enregistrements lituaniens, nous pouvons conserver les enregistrements dont nous avons besoin dans un cache indexé comme décrit dans la documentation MS. Lorsque nous exécutons nos rapports sur les ventes lituaniennes en 2008, notre requête recherche dans un index d'une profondeur de seulement 7 (Log2 (100) avec quelques feuilles inutilisées). Si nous devions faire de même sans la VUE et en nous appuyant simplement sur un index dans la table, nous aurions à parcourir une arborescence d'index avec une profondeur de recherche de 21!

De toute évidence, la vue elle-même nous fournirait un avantage de performance (3x) par rapport à la simple utilisation de l'index seul. J'ai essayé d'utiliser un exemple réel, mais vous remarquerez qu'une simple liste de ventes lituaniennes nous donnerait un avantage encore plus grand.

Notez que j'utilise simplement un arbre b droit pour mon exemple. Bien que je sois assez certain que SQL Server utilise une variante d'une arborescence b, je ne connais pas les détails. Néanmoins, le point tient.

Mise à jour 3: la question s'est posée de savoir si une vue indexée utilise uniquement un index placé sur la table sous-jacente. C'est-à-dire, pour paraphraser: "une vue indexée est juste l'équivalent d'un index standard et elle n'offre rien de nouveau ou unique à une vue." Si c'était vrai, bien sûr, alors l'analyse ci-dessus serait incorrecte! Permettez-moi de fournir une citation de la documentation Microsoft qui montre pourquoi je pense que cette critique n'est pas valide ou vraie:

L'utilisation d'index pour améliorer les performances des requêtes n'est pas un nouveau concept; cependant, les vues indexées offrent des avantages de performances supplémentaires qui ne peuvent pas être obtenus à l'aide d'index standard.

Avec la citation ci-dessus concernant la persistance des données dans le stockage physique et d'autres informations dans la documentation sur la façon dont les indices sont créés sur les vues, je pense qu'il est sûr de dire qu'une vue indexée n'est pas seulement un SQL Select mis en cache qui arrive à utiliser un index défini sur la table principale. Ainsi, je continue de maintenir cette réponse.


29
Oui, les vues indexées peuvent considérablement améliorer les performances. Mais les vues indexées ne sont pas seulement des "vues" et, d'une manière générale, les "vues" normales ne sont pas plus rapides que leurs requêtes associées.
BradC

10
@Charles - peu importe qu'il s'agisse de l'index, le fait qu'une vue puisse exploiter l'index et qu'une requête brute ne le soit pas suffit
annakata

195
/ applaudissez @Mark pour avoir résisté et argumenté rationnellement celui-ci
annakata

17
Oh, mec, j'ai obtenu 8 downvotes sur celui-ci! Je suis étonné que les gens votent si vite sans au moins avoir le courage de Charles pour faire valoir leur point de vue.
Mark Brittingham

8
Puisqu'une table ne peut avoir qu'un seul index clusterdee, et que vous POUVEZ créer un index cluster séparé sur une vue, (puisque les champs de l'index cluster sont persistés indépendamment dans les pages d'index), ceci est une triche (work-arounnd?) Qui vous permet d'obtenir DEUX index clusterisés sur une table.
Charles Bretana

51

De manière générale, non. Les vues sont principalement utilisées pour plus de commodité et de sécurité, et ne produiront pas (en elles-mêmes) de gain de vitesse.

Cela dit, SQL Server 2000 et versions ultérieures ont une fonctionnalité appelée Vues indexées qui peut améliorer considérablement les performances, avec quelques mises en garde:

  1. Toutes les vues ne peuvent pas être transformées en une vue indexée; ils doivent suivre un ensemble spécifique de lignes directrices , qui (entre autres restrictions) des moyens que vous ne pouvez pas inclure des éléments de requête communs comme COUNT, MIN, MAXou TOP.
  2. Les vues indexées utilisent l'espace physique dans la base de données, tout comme les index sur une table.

Cet article décrit les avantages et les limitations supplémentaires des vues indexées :

Vous pouvez…

  • La définition de la vue peut référencer une ou plusieurs tables dans la même base de données.
  • Une fois l'index cluster unique créé, des index non cluster supplémentaires peuvent être créés sur la vue.
  • Vous pouvez mettre à jour les données dans les tables sous-jacentes, y compris les insertions, les mises à jour, les suppressions et même les tronques.

Vous ne pouvez pas ...

  • La définition de la vue ne peut pas référencer d'autres vues ou tables dans d'autres bases de données.
  • Il ne peut pas contenir COUNT, MIN, MAX, TOP, jointures externes ou quelques autres mots clés ou éléments.
  • Vous ne pouvez pas modifier les tables et colonnes sous-jacentes. La vue est créée avec l'option WITH SCHEMABINDING.
  • Vous ne pouvez pas toujours prédire ce que fera l'optimiseur de requêtes. Si vous utilisez Enterprise Edition, il considérera automatiquement l'index cluster unique comme une option pour une requête - mais s'il trouve un «meilleur» index, celui-ci sera utilisé. Vous pouvez forcer l'optimiseur à utiliser l'index via le conseil WITH NOEXPAND - mais soyez prudent lorsque vous utilisez un conseil.

3
totalement en désaccord ... la lecture à partir d'une vue permet de réécrire le SQL .. et il est généralement PLUS RAPIDE de lire à partir d'une vue (qu'à partir d'un vidage de la vue).
Aaron Kempf

@AaronKempf, j'aimerais voir des références à ce sujet, ce n'est pas mon expérience. Lorsque je recherche «voir SQL réécrit», tous les résultats que j'obtiens se réfèrent à Oracle, pas au serveur SQL, par exemple docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC

J'étais juste en train de faire un benchmarking dessus hier, j'ai été stupéfait .. essentiellement si je fais un vidage d'une vue (dans une table) toute requête que j'exécute est plus lente .. parce que la plupart des requêtes passent par la vue comme du beurre et sont réécrites par l'optimiseur de requête .. Du moins, c'est ce que je suppose. J'essaierai d'écrire une entrée de blog bientôt, le benchmarking était assez fascinant. Fondamentalement, les vues aident énormément les performances.
Aaron Kempf

@AaronKempf Je ne suis pas sûr que ce soit le même scénario que la question d'origine (qui concerne une requête par rapport à la mise en requête identique). Quoi qu'il en soit, je ne vois pas comment la matérialisation d'une vue dans une table la rendrait plus LENTE (c'est exactement ce que fait une vue indexée), à ​​moins que votre nouvelle table n'ait pas de bons index.
BradC

1
Brad; J'ai écrit un très mauvais article de blog sur la façon dont les vues m'économisent 99% de mes performances dans cette situation .. Je prévois d'écrire quelques autres articles, mais je sais que je dois ajouter plus de détails à ce sujet. Cela vous dérange de jeter un œil à cela et de me dire ce que vous pensez de ma description? Je sais que cela n'aura plus de sens (jusqu'à ce que j'aie 2-3 autres articles) .. mais je suis follement amoureux des vues, et je l'ai depuis longtemps! accessadp.com/2013/01/22/do-views-increase-performance
Aaron Kempf

14

Dans SQL Server au moins, les plans de requête sont stockés dans le cache de plan pour les vues et les requêtes SQL ordinaires, en fonction des paramètres de requête / vue. Pour les deux, ils sont supprimés du cache lorsqu'ils n'ont pas été utilisés pendant une période suffisamment longue et que l'espace est nécessaire pour une autre requête nouvellement soumise. Après quoi, si la même requête est émise, elle est recompilée et le plan est remis dans le cache. Donc non, il n'y a pas de différence, étant donné que vous réutilisez la même requête SQL et la même vue avec la même fréquence.

De toute évidence, en général, une vue, par sa nature même (que quelqu'un pensait qu'elle devait être utilisée assez souvent pour en faire une vue) est généralement plus susceptible d'être "réutilisée" que toute instruction SQL arbitraire.


14

EDIT: J'avais tort et vous devriez voir Marks répondre ci-dessus.

Je ne peux pas parler d'expérience avec SQL Server , mais pour la plupart des bases de données, la réponse serait non. Le seul avantage potentiel que vous obtenez, en termes de performances, de l'utilisation d'une vue est qu'elle pourrait potentiellement créer des chemins d'accès basés sur la requête. Mais la principale raison d'utiliser une vue est de simplifier une requête ou de normaliser un moyen d'accéder à certaines données d'une table. D'une manière générale, vous n'obtiendrez pas d'avantage de performance. Je peux me tromper, cependant.

Je proposerais un exemple modérément plus compliqué et le temps vous-même pour voir.


1
une autre raison des vues est d'aider au contrôle d'accès dans les modèles basés sur les rôles
annakata

1
Vous vous trompez sur les améliorations de performances. Je n'ai pas expliqué suffisamment pour convaincre certaines personnes dans mon commentaire d'origine, mais MS a une documentation explicite sur la façon d'utiliser les vues pour améliorer les performances. Voir ma réponse (maintenant fortement décotée) ci-dessous.
Mark Brittingham

7

Cela peut être plus rapide si vous créez une vue matérialisée ( avec liaison de schéma ). Les vues non matérialisées s'exécutent comme la requête standard.


schemabinding a peu à voir avec les performances, il lie le schéma de la vue à la table sous-jacente afin qu'il reste synchronisé et constitue une pré-exigence pour les vues indexées.
Sam Saffron

5

D'après ce que je comprends, il y a quelque temps, une vue serait plus rapide car SQL Server pouvait stocker un plan d'exécution et ensuite simplement l'utiliser au lieu d'essayer d'en trouver un à la volée. Je pense que les gains de performances de nos jours ne sont probablement pas aussi importants qu'ils l'étaient autrefois, mais je dois deviner qu'il y aurait une amélioration marginale pour utiliser la vue.


C'était ma compréhension: l'habitude importait, n'est plus
annakata

N'est pas du point de vue des performances - fait comme un moyen de restriction d'accès. Mais ce serait un autre sujet. ;)
AnonJr

oh bien sûr, beaucoup de bonnes raisons d'utiliser des vues, pas une seule pour utiliser des requêtes brutes: P
annakata

4

Une vue est certainement meilleure qu'une requête imbriquée pour SQL Server. Sans savoir exactement pourquoi c'est mieux (jusqu'à ce que je lise le post de Mark Brittingham), j'avais effectué des tests et connu des améliorations de performances presque choquantes lors de l'utilisation d'une vue par rapport à une requête imbriquée. Après avoir exécuté chaque version de la requête plusieurs centaines de fois de suite, la version d'affichage de la requête s'est terminée en deux fois moins de temps. Je dirais que c'est une preuve suffisante pour moi.


Merci Jordan ... heureux d'entendre que toute cette théorie fonctionne dans le monde réel .
Mark Brittingham

J'ai de l'expérience avec la vue imbriquée (vue en vue) et les performances étaient très mauvaises. Lorsque toutes les vues ont été réécrites dans les sous-sélections, les performances ont été beaucoup plus rapides, donc il y a peut-être une place pour des tests sérieux.
Muflix

2

Je m'attendrais à ce que les deux requêtes fonctionnent de manière identique. Une vue n'est rien de plus qu'une définition de requête stockée, il n'y a pas de mise en cache ou de stockage de données pour une vue. L'optimiseur transformera efficacement votre première requête en votre deuxième requête lorsque vous l'exécuterez.


Si la vue est un petit ensemble de champs et que ces champs sont ensuite couverts par un index, SQL Server est-il suffisamment intelligent pour utiliser cet index de couverture lors de l'exécution de la deuxième forme de requête?
AnthonyWJones

1

Cela dépend complètement de la situation. Les vues indexées MS SQL sont plus rapides qu'une vue ou requête normale, mais les vues indexées ne peuvent pas être utilisées dans un environnement de base de données en miroir (MS SQL).

Une vue dans n'importe quel type de boucle provoquera un sérieux ralentissement car la vue est repeuplée chaque fois qu'elle est appelée dans la boucle. Identique à une requête. Dans cette situation, une table temporaire utilisant # ou @ pour contenir vos données à parcourir est plus rapide qu'une vue ou une requête.

Tout dépend donc de la situation.


0

Il n'y a pas de différence pratique et si vous lisez BOL, vous constaterez que votre ancien SQL SELECT * FROM X profite de la mise en cache du plan, etc.


0

Il devrait y avoir un gain insignifiant à conserver le plan d'exécution, mais ce sera négligeable.


0

Le but d'une vue est d'utiliser la requête encore et encore. À cette fin, SQL Server, Oracle, etc. fournira généralement une version «mise en cache» ou «compilée» de votre vue, améliorant ainsi ses performances. En général, cela devrait fonctionner mieux qu'une requête "simple", bien que si la requête est vraiment très simple, les avantages peuvent être négligeables.

Maintenant, si vous effectuez une requête complexe, créez la vue.


0

À mon avis, l'utilisation de la vue est un peu plus rapide qu'une requête normale. Ma procédure stockée prenait environ 25 minutes (en travaillant avec différents jeux d'enregistrements plus volumineux et plusieurs jointures) et après avoir utilisé la vue (non groupée), les performances étaient juste un peu plus rapides mais pas significatives du tout. J'ai dû utiliser d'autres techniques / méthodes d'optimisation des requêtes pour en faire un changement spectaculaire.


La façon dont nous écrivons / concevons la requête est très importante.
kta

J'ai trouvé que l'utilisation des CTE pour limiter les données renvoyées par une table et ensuite faire tout le travail / jointures, etc. sur les CTE a considérablement amélioré les performances dans de nombreux cas
MattE

0

Sélectionner à partir d'une vue ou d'une table n'aura pas trop de sens.

Bien sûr, si la vue n'a pas de jointures, de champs, etc. inutiles. Vous pouvez vérifier le plan d'exécution de vos requêtes, jointures et index utilisés pour améliorer les performances de la vue.

Vous pouvez même créer un index sur les vues pour des exigences de recherche plus rapides. http://technet.microsoft.com/en-us/library/cc917715.aspx

Mais si vous recherchez comme '% ...%', le moteur SQL ne bénéficiera pas d'un index sur la colonne de texte. Si vous pouvez forcer vos utilisateurs à effectuer des recherches comme «...%», ce sera rapide

renvoyé à la réponse sur les forums asp: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+


0

Contre toute attente, les vues sont beaucoup plus lentes dans certaines circonstances.

Je l'ai découvert récemment lorsque j'ai eu des problèmes avec des données extraites d'Oracle qui devaient être massées dans un autre format. Peut-être 20k lignes source. Une petite table. Pour ce faire, nous avons importé les données Oracle aussi inchangées que possible dans une table, puis utilisé des vues pour extraire les données. Nous avions des vues secondaires basées sur ces vues. Peut-être 3-4 niveaux de vues.

L'une des dernières requêtes, qui a extrait peut-être 200 lignes, prendrait plus de 45 minutes! Cette requête était basée sur une cascade de vues. Peut-être 3-4 niveaux de profondeur.

Je pouvais prendre chacune des vues en question, insérer son sql dans une requête imbriquée et l'exécuter en quelques secondes.

Nous avons même constaté que nous pouvions même écrire chaque vue dans une table temporaire et interroger celle-ci à la place de la vue et c'était encore beaucoup plus rapide que d'utiliser simplement des vues imbriquées.

Ce qui était encore plus étrange, c'était que les performances allaient bien jusqu'à ce que nous atteignions une certaine limite de lignes source tirées dans la base de données, les performances venaient de tomber d'une falaise en l'espace de quelques jours - quelques lignes source supplémentaires suffisaient.

Donc, utiliser des requêtes qui tirent des vues qui tirent des vues est beaucoup plus lent qu'une requête imbriquée - ce qui n'a aucun sens pour moi.


-1

J'ai parcouru ce fil et je voulais juste partager ce post de Brent Ozar comme quelque chose à considérer lors de l'utilisation des groupes de disponibilité.

Rapport de bug de Brent Ozar

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.