Comment créer une vue avec SNAPSHOT_MATERIALIZATION dans SQL Server 2017?


36

SQL Server 2017 comporte quelques nouvelles procédures stockées:

  • sp_refresh_single_snapshot_view - paramètre d'entrée pour @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - paramètre d'entrée pour @rgCode int

Et nouvelles entrées dans sys.messages:

  • 10149 - Impossible de créer un index comportant SNAPSHOT_MATERIALIZATION dans la vue '%. * Ls' car la définition de la vue contient des tables optimisées pour la mémoire.
  • 10642 - SNAPSHOT_MATERIALIZATION ne peut pas être défini pour l'index '%. * Ls' sur '%. * Ls' car il ne s'applique qu'aux index sur les vues.
  • 10643 - SNAPSHOT_MATERIALIZATION ne peut pas être défini pour '%. * Ls' sur '%. * Ls' car il ne s'applique qu'aux index clusterisés sur les vues.
  • 10648 - SNAPSHOT_MATERIALIZATION ne peut pas être défini pour l'index partitionné '%. * Ls' sur '%. * Ls'.
  • 10649 - Impossible de créer l'index non clusterisé '%. * Ls' sur '%. * Ls' comportant un index clusterisé '%. * Ls' avec SNAPSHOT_MATERIALIZATION.
  • 10650 - L'actualisation des vues d'instantané nécessite l'activation de l'isolation de l'instantané sur la base de données.
  • 3760 - Impossible de supprimer l'index '%. * Ls' dans la vue '%. * Ls' contenant SNAPSHOT_MATERIALIZATION.
  • 4524 - Impossible de modifier la vue '%. * Ls' car elle comporte une matérialisation d'instantané.
  • 4525 - Impossible d'utiliser l'indicateur '% ls' sur la vue '%. * Ls' comportant une matérialisation d'instantané avant l'actualisation de la vue.

Et nouveaux événements étendus:

Affichage instantané des événements étendus

Alors, comment pouvons-nous créer une vue matérialisée par un instantané? (Microsoft ne l'a pas encore documentée, évidemment.) Voici un résumé des choses que j'ai essayées jusqu'à présent et qui n'ont pas fonctionné.

Réponses:


55

Tu ne peux pas. La fonctionnalité est désactivée en 2017 RTM.


Cela dit, vous pouvez ...

Utiliser AdventureWorks:

CREATE VIEW dbo.TH
WITH SCHEMABINDING
AS
SELECT P.ProductID, COUNT_BIG(*) AS cbs
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
GROUP BY P.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Les modifications apportées aux tables sous-jacentes ne sont pas immédiatement reflétées dans la vue (comme c'est normalement le cas avec SQL Server). De même, les modifications de données sur les tables sous-jacentes ne doivent pas nécessairement conserver la vue indexée par image instantanée.

Pour actualiser le contenu de la vue, il est nécessaire d'appeler l'une des nouvelles procédures stockées:

EXECUTE sys.sp_refresh_single_snapshot_view
    @view_name = N'dbo.TH',
    @rgCode = 0; -- don't know what this is for yet

Ceci produit le plan d'exécution:

Plan

Cela ne fonctionnera probablement pas pour vous, car un indicateur de trace non documenté est nécessaire ou vous devez effectuer la chose particulièrement désagréable que j'ai faite: écrire dans l'emplacement mémoire contenant l'indicateur de fonctionnalité (à l'aide d'un débogueur) pour activer cette fonctionnalité.

Si vous êtes curieux, le drapeau de fonctionnalité est l'octet à sqllang!g_featureSwitchesLangSvc+0x10f. Il est vérifié pendant sqllang!SpRefreshSingleSnapshotView.

Si vous souhaitez continuer à jouer et êtes prêt à accepter les conséquences du piratage du code SQL Server pendant son exécution et de l'utilisation d'une fonctionnalité qui, de l'avis de Microsoft, n'est pas encore prête:

  1. Attachez un débogueur au processus SQL Server 2017. J'utilise WinDbg.
  2. Définir un point d'arrêt:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Reprendre SQL Server en utilisant la commande Go ( g)

  4. Créez la vue ci-dessus, mais pas encore l'index cluster unique
  5. Exécutez la sys.sp_refresh_single_snapshot_viewcommande ci-dessus
  6. Lorsque le point d'arrêt est atteint, avancez jusqu'à ce que la ligne de code apparaisse:

    cmp byte ptr [sqllang!g_featureSwitchesLangSvc+0x10f (00007fff`328dfbcf)],0

    Le décalage peut être différent dans d'autres versions, par exemple en 2017 RTM CU3, il est sqllang!g_featureSwitchesLangSvc+0x114

  7. L'adresse mémoire à l'intérieur des parenthèses peut être différente. Utilisez celui que vous voyez.

  8. Utilisez la commande display memory pour voir la valeur actuelle à l'adresse de mémoire trouvée:

    db 00007fff`328dfbcf L1
  9. Cela devrait afficher un zéro, indiquant que la fonctionnalité est désactivée.

  10. Changez le zéro en un, en utilisant la commande entrer valeurs (encore avec votre adresse mémoire):

    eb 00007fff`328dfbcf 1
  11. Désactivez le point d'arrêt et reprenez l'exécution de SQL Server.

  12. La fonctionnalité est maintenant activée.
  13. Générez l'index cluster unique sur la vue.
  14. S'amuser.

Note SNAPSHOT_MATERIALIZATIONnous permet de matérialiser un instantané d'une spécification de requête qui normalement ne pourrait pas être indexé, par exemple, les utilisations ci-dessous MAX:

CREATE VIEW dbo.TH2
WITH SCHEMABINDING
AS
SELECT TH.ProductID, MaxTransactionID = MAX(TH.TransactionID)
FROM Production.TransactionHistory AS TH
GROUP BY TH.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH2 (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Résultat:

Commandes terminées avec succès.
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.