Il s'agit d'une tentative d'améliorer le travail de Max Vernon . Dans sa solution, il propose d'utiliser 2 index sur la vue et un objet statistique.
Le 1er index est clusterisé, ce qui est en fait nécessaire car contrairement à un index non clusterisé sur une table, une erreur sera générée si la création d'un index non clusterisé sur la vue est tentée sans avoir au préalable un index clusterisé.
Le 2e index est un index non cluster, qui est utilisé comme index derrière la requête. Dans la section des commentaires de sa réponse, j'ai demandé ce qui se passerait si un index cluster était utilisé au lieu d'un index non cluster.
L'analyse suivante tente de répondre à cette question.
J'utilise son même code exact, sauf que je ne crée pas d'index non cluster sur la vue.
Je ne crée pas non plus d'objet de statistiques. Si vous suivez et utilisez SQL Server Management Studio (SSMS) pour entrer le code ci-dessous, vous devez savoir que vous pouvez voir des lignes rouges ondulées - qui ressemblent à des erreurs. Ce ne sont (probablement) pas des erreurs, mais impliquent un problème avec intellisense.
Vous pouvez désactiver Intellisense ou simplement ignorer les erreurs et exécuter les commandes. Ils doivent se terminer sans erreur.
-- Create the test table that uses a computed column.
USE tempdb;
CREATE TABLE dbo.PersistedViewTest
(
PersistedViewTest_ID INT NOT NULL
CONSTRAINT PK_PersistedViewTest
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, SomeData VARCHAR(2000) NOT NULL
, TestComputedColumn AS (PersistedViewTest_ID - 1) PERSISTED
);
GO
-- Insert some test data into the table.
INSERT INTO dbo.PersistedViewTest (SomeData)
SELECT o.name + o1.name + o2.name
FROM sys.objects o
CROSS JOIN sys.objects o1
CROSS JOIN sys.objects o2;
GO
Le plan d'exécution suivant (sans vue vue / index) est produit après l'exécution de la requête suivante sur la table:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Cela donne une référence à comparer. Notez qu'une fois la requête terminée, un objet de statistiques a été créé (_WA_Sys_00000003_1FCDBCEB). L'objet de statistiques PK_PersistedViewTest a été créé lors de la création de l'index de table en cluster.
Ensuite, la vue filtrée et l'index cluster sur cette vue sont créés:
-- Create filtered view on the computed column.
CREATE VIEW dbo.PersistedViewTest_View
WITH SCHEMABINDING
AS
SELECT PersistedViewTest_ID, SomeData, TestComputedColumn
FROM dbo.PersistedViewTest
WHERE TestComputedColumn < CONVERT(INT, 27);
GO
-- Create unique clustered index to persist the values, including the computed column.
CREATE UNIQUE CLUSTERED INDEX IX_PersistedViewTest
ON dbo.PersistedViewTest_View(PersistedViewTest_ID);
GO
Maintenant, essayons de relancer la requête, mais cette fois par rapport à la vue:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Le nouveau plan d'exécution est désormais:
Si l'on en croit le nouveau plan, après l'ajout de la vue et de l'index cluster sur cette vue, les statistiques semblent indiquer que le temps requis pour exécuter la requête a maintenant doublé. Notez également qu'aucun nouvel objet de statistiques n'a été créé pour prendre en charge le nouvel index après l'exécution de la requête, ce qui est différent de la requête sur la table.
Le plan de requête suggère toujours que la création d'un index non cluster serait très utile pour améliorer les performances de la requête. Cela signifie-t-il donc qu'un index non cluster doit être ajouté à la vue avant d'obtenir l'amélioration des performances souhaitée? Il y a une dernière chose à essayer. Modifiez la requête pour utiliser l'option "WITH NOEXPAND":
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Il en résulte le plan de requête suivant:
Ce plan d'exécution ressemble assez à celui qui a été produit avec l'index non cluster donné dans la réponse de Max Vernon. Mais, celui-ci se fait avec un index de moins (non cluster) et un objet de statistiques en moins.
Il s'avère que l'option NOEXPAND doit être utilisée avec les versions express et standard de SQL Server pour utiliser correctement une vue indexée. Paul White a un excellent article qui expose les avantages de l'utilisation de l'option NOEXPAND. Il recommande également que cette option soit utilisée avec l'édition entreprise pour garantir que la garantie d'unicité fournie par les index de vue est utilisée par l'optimiseur.
L'analyse ci-dessus a été effectuée avec l'édition express de SQL Sever 2014. Je l'ai également essayée avec l'édition développeur de SQL Server 2016. L'option NOEXPAND ne semble pas être requise avec l'édition de développement pour obtenir des gains de performances, mais est toujours recommandée. .
Il y a moins de 5 mois, Microsoft a rendu les éditions développeur gratuites . La licence limite l'utilisation au développement uniquement, ce qui signifie que la base de données ne peut pas être utilisée dans un environnement de production. Donc, si vous avez cherché à tester des tables optimisées en mémoire, le chiffrement, R, etc., vous n'avez plus d'excuse sans licence. Je l'ai installé avec succès sur mon ordinateur il y a quelques jours avec SQL Server 2014 Express sans aucun problème.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.