Résolution d'index sur les vues

Comme avec tout index, SQL Server choisit d'utiliser une vue indexée dans son plan de requête uniquement si l'optimiseur de requête le juge opportun.

Les vues indexées peuvent être créées dans n'importe quelle version de SQL Server. Dans SQL Server Enterprise, l'optimiseur de requête prend automatiquement en considération la vue indexée. Pour utiliser une vue indexée dans toutes les autres éditions, vous devez recourir à l'indicateur de table NOEXPAND.

L'optimiseur de requête SQL Server utilise une vue indexée lorsque les conditions suivantes sont satisfaites :

  • Ces options de session sont activées (ON) :

    • ANSI_NULLS

    • ANSI_PADDING

    • ANSI_WARNINGS

    • ARITHABORT

    • CONCAT_NULL_YIELDS_NULL

    • QUOTED_IDENTIFIER

    • L'option de session NUMERIC_ROUNDABORT est désactivée (OFF).

  • L'optimiseur de requête trouve une correspondance entre les colonnes d'index des vues et les éléments de la requête, notamment :

    • Prédicats de la condition de recherche dans la clause WHERE

    • Opérations de jointure

    • Fonctions d'agrégation

    • Clauses GROUP BY

    • Références de table

  • Le coût estimé de l'utilisation de l'index est le plus faible de tous les mécanismes d'accès envisagés par l'optimiseur de requête.

  • Dans la requête, vous devez appliquer le même ensemble d'indicateurs à chaque table que vous référencez, soit directement, soit en développant une vue afin d'accéder à ses tables sous-jacentes, et qui correspond à une référence de table dans la vue indexée.

    [!REMARQUE]

    Les indicateurs READCOMMITTED et READCOMMITTEDLOCK sont toujours considérés comme des indicateurs différents dans ce contexte, indépendamment du niveau d'isolation de la transaction en cours.

En dehors des exigences relatives aux indicateurs de table et aux options SET, l'optimiseur de requête emploie ces mêmes règles pour déterminer si l'index d'une table couvre une requête. Vous n'avez pas besoin de spécifier autre chose dans la requête pour utiliser une vue indexée.

Une requête ne doit pas faire référence explicitement à une vue indexée dans la clause FROM pour permettre à l'optimiseur de requête d'utiliser la vue indexée. Si la requête contient des références à des colonnes dans des tables de base qui sont également présentes dans la vue indexée, et si l'optimiseur de requête estime que l'emploi de la vue indexée offre le mécanisme d'accès le moins coûteux, il choisit la vue indexée, un peu comme il choisit les index des tables de base lorsque ceux-ci ne sont pas directement référencés dans une requête. L'optimiseur de requête peut choisir la vue lorsqu'elle contient des colonnes qui ne sont pas référencées par la requête, à condition que cette dernière offre l'option la moins coûteuse pour couvrir une ou plusieurs colonnes spécifiées dans la requête.

L'optimiseur de requête traite une vue indexée référencée dans la clause FROM comme une vue standard. L'optimiseur de requête développe la définition de la vue dans la requête au début du processus d'optimisation. Ensuite, la mise en correspondance des éléments de la vue indexée est réalisée. La vue indexée peut être utilisée dans le plan d'exécution final sélectionné par l'optimiseur ou, sinon, le plan peut matérialiser les données nécessaires à partir de la vue en accédant aux tables de base référencées par celle-ci. L'optimiseur choisit la solution la plus économique.

Utilisation d'indicateurs avec les vues indexées

Vous pouvez empêcher l'utilisation d'index de vue pour une requête à l'aide de l'indicateur de requête EXPAND VIEWS ou recourir à l'indicateur de table NOEXPAND afin d'imposer l'utilisation d'un index pour une vue indexée spécifiée dans la clause FROM d'une requête. Toutefois, vous devez laisser l'optimiseur de requête déterminer dynamiquement les meilleures méthodes d'accès à utiliser pour chaque requête. Limitez l'utilisation des indicateurs EXPAND et NOEXPAND aux cas spécifiques où les tests ont démontré qu'elles améliorent les performances de façon significative.

L'option EXPAND VIEWS ordonne à l'optimiseur de requête de ne pas utiliser des index de vue pour toute la requête.

Lorsque NOEXPAND est spécifié dans une vue, l'optimiseur de requête envisage l'utilisation de n'importe quel index défini sur la vue. NOEXPAND spécifié avec la clause INDEX() facultative force l'optimiseur de requête à utiliser les index spécifiés. NOEXPAND peut être spécifié uniquement pour une vue indexée et ne peut pas être spécifié pour une vue qui n'a pas été indexée.

Lorsque ni NOEXPAND ni EXPAND VIEWS ne sont spécifiés dans une requête qui contient une vue, celle-ci est développée de manière à permettre l'accès aux tables sous-jacentes. Si la requête qui compose la vue contient des indicateurs de table, ceux-ci sont propagés aux tables sous-jacentes. (Ce processus est expliqué en détail dans Résolution de vues.) Si les ensembles d'indicateurs existant sur les tables sous-jacentes de la vue sont identiques, la requête peut être mise en correspondance avec une vue indexée. La plupart du temps, ces indicateurs correspondent les uns aux autres car ils sont hérités directement de la vue. Toutefois, si la requête référence des tables au lieu de vues et que les indicateurs appliqués directement à ces tables ne sont pas identiques, cette requête ne peut pas être mise en correspondance avec une vue indexée. Si les indicateurs INDEX, PAGLOCK, ROWLOCK, TABLOCKX, UPDLOCK ou XLOCK s'appliquent aux tables référencées dans la requête une fois la vue développée, la requête ne peut pas être mise en correspondance avec la vue indexée.

Si un indicateur de table de la forme INDEX (index_val[ ,...n] ) référence une vue dans une requête et que vous ne spécifiez pas l'indicateur NOEXPAND, l'indicateur d'index est ignoré. Pour spécifier l'utilisation d'un index particulier, utilisez NOEXPAND.

En règle générale, lorsque l'optimiseur de requête fait correspondre une vue indexée avec une requête, tous les indicateurs spécifiés sur les tables ou vues dans la requête sont appliqués directement à la vue indexée. Si l'optimiseur de requête choisit de ne pas utiliser une vue indexée, tous les indicateurs sont propagés directement aux tables référencées dans la vue. Pour plus d'informations, consultez Résolution de vues. Cette propagation ne s'applique pas aux indicateurs de jointure. Ils ne sont appliqués qu'à leur emplacement initial dans la requête. Les indicateurs de jointure ne sont pas envisagés par l'optimiseur de requête lors de la mise en correspondance des requêtes avec les vues indexées. Si un plan de requête utilise une vue indexée qui correspond à une partie d'une requête contenant un indicateur de jointure, celui-ci n'est pas utilisé dans le plan.

SQL Server 2008 n'autorise pas l'utilisation d'indicateurs dans les définitions de vues indexées. Dans les modes de compatibilité 80 et supérieurs, SQL Server ignore les indicateurs présents dans les définitions de vues indexées lorsqu'il gère ces définitions ou qu'il exécute des requêtes qui utilisent des vues indexées. Bien que l'utilisation d'indicateurs dans les définitions de vues indexées ne génère pas d'erreur de syntaxe dans le mode de compatibilité 80, ils sont ignorés.