Estou com dificuldades para configurar uma exibição indexada no cenário a seguir para que a consulta a seguir seja executada sem duas verificações de índice em cluster. Sempre que eu crio uma exibição de índice para esta consulta e a uso, ela parece ignorar qualquer índice que eu coloquei nela:
-- +++ 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
A configuração da tabela é a seguinte:
- duas mesas
- eles são unidos por uma junção interna pela consulta acima
- e ordenada por uma coluna da primeira e, em seguida, uma coluna da segunda tabela pela consulta acima; apenas TOP 1 está selecionado
(no script abaixo, também existem algumas linhas para gerar dados de teste, caso isso ajude a reproduzir o problema)
-- +++ 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
A exibição indexada provavelmente deve ser definida da seguinte maneira e a consulta TOP 1 resultante está abaixo. Mas de quais índices eu preciso para que essa consulta tenha um desempenho melhor do que sem a exibição indexada?
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
fonte