Indexation des vues avec un CTE

Donc, je viens de découvrir que SQL Server 2008 ne vous permet pas d'indexer une vue avec un CTE dans la définition, mais il vous permet de alter la requête à append with schemabinding dans la définition de la vue. Y a-t-il une bonne raison à cela? Cela a-t-il un sens pour une raison que je ne connais pas? J'avais l'printing que le but principal de WITH SCHEMABINDING était de vous permettre d'indexer une vue

nouveau et amélioré avec plus d'action de requête

 ;with x as ( select rx.pat_id ,rx.drug_class ,count(*) as counts from rx group by rx.pat_id,rx.drug_class ) select x.pat_id ,x.drug_class ,x.counts ,SUM(c.std_cost) as [Healthcare Costs] from x inner join claims as c on claims.pat_id=x.pat_id group by x.pat_id,x.drug_class,x.counts 

Et le code pour créer l'index

 create unique clustered index [TestIndexName] on [dbo].[MyView] ( pat_id asc, drug_class asc, counts asc) 

  1. Vous ne pouvez pas indexer une vue avec un CTE. Même si la vue peut avoir SCHEMABINDING . Pense-y de cette façon. Pour indexer une vue, elle doit répondre à deux conditions (et à bien d'autres): (a) qu'elle a été créée WITH SCHEMABINDING et (b) qu'elle ne contient pas de CTE. Pour schématiser une vue, il n'est pas nécessaire de remplir la condition qu'elle ne contienne pas de CTE.

  2. Je ne suis pas convaincu qu'il existe un scénario où une vue a un CTE et bénéficiera d'être indexée. Ceci est en marge de votre question, mais mon instinct est que vous essayez d'indexer cette vue pour la rendre plus rapide. Une vue indexée ne va pas nécessairement être plus rapide qu'une requête sur les tables de base – il y a des ressortingctions pour une raison, et il n'y a que des cas d'utilisation particuliers où cela a du sens. S'il vous plaît faites attention à ne pas indexer aveuglément toutes vos vues comme un button magique "aller plus vite". Souvenez-vous également qu'une vue indexée nécessite une maintenance. Cela augmentera donc le coût de toutes les opérations DML de votre charge de travail qui affectent la (les) table (s) de base.

  3. Schemabinding n'est pas seulement pour indexer les vues. Il peut également être utilisé sur des objects tels que les fonctions UDF pour aider à persuader le déterminisme, sur les vues et les fonctions pour empêcher les modifications du schéma sous-jacent et, dans certains cas, améliorer les performances (par exemple, lorsqu'un file UDF n'est pas lié au schéma l'optimiseur peut avoir à créer un spool de table pour gérer les modifications DDL sous-jacentes). Donc, s'il vous plaît, ne pensez pas que c'est bizarre que vous puissiez lier une vue à un schéma, mais vous ne pouvez pas l'indexer. L'indexing d'une vue l'exige, mais la relation n'est pas mutuelle.


Pour votre scénario spécifique, je recommand ceci:

 CREATE VIEW dbo.PatClassCounts WITH SCHEMABINDING AS SELECT pat_id, drug_class, COUNT_BIG(*) AS counts FROM dbo.rx GROUP BY pat_id, drug_class; GO CREATE UNIQUE CLUSTERED INDEX ON dbo.PatClassCounts(pat_id, drug_class); GO CREATE VIEW dbo.ClaimSums WITH SCHEMABINDING AS SELECT pat_id, SUM(c.std_cost) AS [Healthcare Costs], COUNT_BIG(*) AS counts FROM dbo.claims GROUP BY pat_id; GO CREATE UNIQUE CLUSTERED INDEX ON dbo.ClaimSums(pat_id); GO 

Maintenant, vous pouvez créer une vue non indexée qui fait juste une jointure entre ces deux vues indexées, et elle utilisera les index (vous devrez peut-être utiliser NOEXPAND sur une édition inférieure, pas sûr):

 CREATE VIEW dbo.OriginalViewName WITH SCHEMABINDING AS SELECT p.pat_id, p.drug_class, p.counts, c.[Healthcare Costs] FROM dbo.PatClassCounts AS p INNER JOIN dbo.ClaimSums AS c ON p.pat_id = c.pat_id; GO 

Maintenant, tout ceci suppose qu'il vaut la peine de pré-agréger ces informations – si vous exécutez cette requête rarement, mais datatables sont beaucoup modifiées, il peut être préférable de ne pas créer de vues indexées.

Notez également que SUM(std_cost) de la vue ClaimSums sera la même pour chaque combinaison pat_id + drug_class , car elle est seulement agrégée à pat_id . Je suppose qu'il pourrait y avoir un drug_class dans la table des claims qui devrait faire partie des critères de la jointure, mais je ne suis pas sûr. Si tel est le cas, je pense que cela pourrait être réduit à une seule vue indexée.