Ich habe Probleme, im folgenden Szenario eine indizierte Ansicht einzurichten, damit die folgende Abfrage ohne zwei Clustered-Index-Scans ausgeführt wird. Immer wenn ich eine Indexansicht für diese Abfrage erstelle und sie dann verwende, scheint sie jeden Index zu ignorieren, den ich darauf gesetzt habe:
-- +++ 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
Das Tabellen-Setup ist wie folgt:
- zwei Tische
- Sie werden durch einen inneren Join durch die obige Abfrage verbunden
- und sortiert nach einer Spalte aus der ersten und dann nach einer Spalte aus der zweiten Tabelle durch die obige Abfrage; Es wird nur TOP 1 ausgewählt
(Im folgenden Skript gibt es auch einige Zeilen zum Generieren von Testdaten, nur für den Fall, dass dies zur Reproduktion des Problems beiträgt.)
-- +++ 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
Die indizierte Ansicht sollte wahrscheinlich wie folgt definiert werden und die resultierende TOP 1-Abfrage ist unten. Aber welche Indizes benötige ich, damit diese Abfrage besser funktioniert als ohne die indizierte Ansicht?
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