web-dev-qa-db-fra.com

Les vues sont-elles optimisées lorsque je leur ajoute une clause WHERE?

Cela fait-il une différence si vous filtrez une vue à l'intérieur ou à l'extérieur de la vue?

Par exemple, y a-t-il une différence entre ces deux requêtes?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Ou

SELECT Id
FROM MyView
WHERE SomeColumn = 1

Et MyView est défini comme

SELECT Id, SomeColumn
FROM MyTable

Et la réponse est-elle différente si la table source se trouve sur un serveur lié?

Je demande parce que je dois interroger une grande table (lignes 44mil) deux fois à partir d'un serveur lié et obtenir un agrégat des résultats. Je veux savoir si je dois créer deux vues pour accéder aux données, une pour chaque requête, ou si je peux m'en tirer avec une seule vue et une clause WHERE.

30
Rachel

Vous ne devriez voir absolument aucune différence dans les plans ou les performances entre ces deux choix. Lorsque la vue est interrogée, elle est étendue à une requête sur la table de base, ce qui signifie que la même recherche ou analyse sera utilisée.

Maintenant, selon le type de données et la sélectivité de MyColumn, si vous vouliez créer un index filtré sur la table de base (lorsque vous passez à SQL Server 2008+), vous pourriez obtenir de meilleures performances, mais cela ne pas être différent via la vue ou sans.

14
Aaron Bertrand

Voici juste un petit exemple montrant qu'il ne devrait pas y avoir de différence. La base de données est la base de données AdventureWorks.

Deux définitions de vue:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Voici la première requête, avec la clause WHERE incluse dans la définition de la vue:

select *
from person.vContactWhere

Voici le plan d'exécution:

enter image description here

Et la deuxième requête, avec la clause WHERE non dans la définition de la vue, mais dans la requête SELECT:

select *
from person.vContactNoWhere
where ContactID = 24

Voici ce plan d'exécution:

enter image description here

Comme vous pouvez le voir sur ces plans d'exécution, ils sont identiques avec des résultats identiques. Je ne connais pas de situation où ce type de logique/conception produirait des résultats différents. Je serais donc prêt à dire que vous êtes en sécurité de toute façon, et que vous préférez les préférences personnelles (ou les procédures de la boutique).

6
Thomas Stringer

Basé sur quoije suislecture , SQL utilisera une vue standard comme une sous-requête lors de la détermination du plan d'exécution.

Donc, en utilisant mon exemple de requête,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

MyView est défini comme

SELECT Id, SomeColumn
FROM MyTable

il doit générer le même plan d'exécution que

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

mais ce plan d'exécution peut être différent de ce qui serait généré avec

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Je ne sais pas si cette réponse serait la même pour les vues indexées

2
Rachel