J'ai du mal à configurer une vue indexée dans le scénario suivant afin que la requête suivante s'exécute sans deux analyses d'index en cluster. Chaque fois que je crée une vue d'index pour cette requête et que je l'utilise, il semble ignorer tout index que je mets dessus:
-- +++ THE QUERY THAT I WANT TO IMPROVE PERFORMANCE-WISE +++
SELECT TOP 1 *
FROM dbo.TB_test1 t1
INNER JOIN dbo.TB_test2 t2 ON t1.PK_ID1 = t2.FK_ID1
ORDER BY t1.somethingelse1
,t2.somethingelse2;
GO
La configuration de la table est la suivante:
- deux tables
- ils sont rejoints par une jointure interne par la requête ci-dessus
- et ordonné par une colonne de la première puis une colonne de la deuxième table par la requête ci-dessus; seul TOP 1 est sélectionné
(dans le script ci-dessous, il y a aussi quelques lignes pour générer des données de test, juste au cas où cela aiderait à reproduire le problème)
-- +++ TABLE SETUP +++ CREATE TABLE [dbo].[TB_test1] ( [PK_ID1] [INT] IDENTITY(1, 1) NOT NULL ,[something1] VARCHAR(40) NOT NULL ,[somethingelse1] BIGINT NOT NULL CONSTRAINT [PK_TB_test1] PRIMARY KEY CLUSTERED ( [PK_ID1] ASC ) ); GO create TABLE [dbo].[TB_test2] ( [PK_ID2] [INT] IDENTITY(1, 1) NOT NULL ,[FK_ID1] [INT] NOT NULL ,[something2] VARCHAR(40) NOT NULL ,[somethingelse2] BIGINT NOT NULL CONSTRAINT [PK_TB_test2] PRIMARY KEY CLUSTERED ( [PK_ID2] ASC ) ); GO ALTER TABLE [dbo].[TB_test2] WITH CHECK ADD CONSTRAINT [FK_TB_Test1] FOREIGN KEY([FK_ID1]) REFERENCES [dbo].[TB_test1] ([PK_ID1]) GO ALTER TABLE [dbo].[TB_test2] CHECK CONSTRAINT [FK_TB_Test1] GO -- +++ TABLE DATA GENERATION +++ -- this might not be the quickest way, but it's only to set up test data INSERT INTO dbo.TB_test1 ( something1, somethingelse1 ) VALUES ( CONVERT(VARCHAR(40), NEWID()) -- something1 - varchar(40) ,ISNULL(ABS(CHECKSUM(NewId())) % 92233720368547758078, 1) -- somethingelse1 - bigint ) GO 100000 RAISERROR( 'Finished setting up dbo.TB_test1', 0, 1) WITH NOWAIT GO INSERT INTO dbo.TB_test2 ( FK_ID1, something2, somethingelse2 ) VALUES ( ISNULL(ABS(CHECKSUM(NewId())) % ((SELECT MAX(PK_ID1) FROM dbo.TB_test1) - 1), 0) + 1 -- FK_ID1 - int ,CONVERT(VARCHAR(40), NEWID()) -- something2 - varchar(40) ,ISNULL(ABS(CHECKSUM(NewId())) % 92233720368547758078, 1) -- somethingelse2 - bigint ) GO 100000 RAISERROR( 'Finished setting up dbo.TB_test2', 0, 1) WITH NOWAIT GO
La vue indexée doit probablement être définie comme suit et la requête TOP 1 résultante est ci-dessous. Mais de quels index ai-je besoin pour que cette requête fonctionne mieux que sans la vue indexée?
CREATE VIEW VI_test
WITH SCHEMABINDING
AS
SELECT t1.PK_ID1
,t1.something1
,t1.somethingelse1
,t2.PK_ID2
,t2.FK_ID1
,t2.something2
,t2.somethingelse2
FROM dbo.TB_test1 t1
INNER JOIN dbo.TB_test2 t2 ON t1.PK_ID1 = t2.FK_ID1
GO
SELECT TOP 1 * FROM dbo.VI_test ORDER BY somethingelse1,somethingelse2
GO
la source