Używam MSSQL Server 2008 R2 i próbuję zoptymalizować moje widoki, gdy natknąłem się na widoki indeksowane. Niestety większość moich widoków używa lewych zewnętrznych połączeń, które nie są obsługiwane w widokach indeksowanych. Po serii badań, nie mam pojęcia, jak najlepiej to osiągnąć. Tak jak ja to widzę, mam następujące opcje:Zindeksowane widoki i lewe połączenia raz na zawsze
1) przekonwertować lewej dołącza do sprzężenia wewnętrzne stosując podstęp, aby symulować LEFT JOIN z "OR (IsNull (a) i IsNull (b))"
Znalazłem to rozwiązanie w kilku miejscach, ale wspomniałem o utracie wydajności.
2) Konwersja lewej łączy się z wewnętrzną łączy się i zastępuje null w pustych kolumny z pustymi GUID (00000000-0000-0000-0000-000000000000) i dodać jeden wiersz w odpowiedniej tablicy z pasującym GUID.
Wydaje się to najbardziej oczywiste pod względem wydajności, ale wydaje się marnowaniem miejsca na każdy wiersz, który w przeciwnym razie byłby NULL.
3) Podziel mój widok na dwa widoki. Pierwszy widok to większość mojej logiki, która jest indeksowalna. Drugi widok wynika z pierwszego widoku i dodanie lewych złączeń.
Pomysł polega na tym, że może nastąpić wzrost wydajności poprzez indeksowanie widoku podstawowego. I nawet zapytanie o widok pochodny przyniosłoby przynajmniej część korzyści z wydajności.
4) NIE indeks moje poglądy
byłoby pozostawienie na stanowisku, tak jest bardziej wydajnych niż którykolwiek z powyższych opcji?
5) Pomysł nie myśleć
I skryptów mój podstawowy scenariusz następująco:
CREATE TABLE [dbo].[tbl_Thumbnails](
[ThumbnailId] [uniqueidentifier] NOT NULL,
[Data] [image] NULL,
[Width] [smallint] NOT NULL,
[Height] [smallint] NOT NULL
CONSTRAINT [PK_tbl_Thumbnails] PRIMARY KEY CLUSTERED
(
[ThumbnailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[tbl_Tags](
[TagId] [uniqueidentifier] NOT NULL,
[ThumbnailId] [uniqueidentifier] NULL
CONSTRAINT [PK_tbl_Tags] PRIMARY KEY CLUSTERED
(
[TagId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE VIEW [dbo].[v_Tags] WITH SCHEMABINDING AS
SELECT dbo.tbl_Tags.TagId, dbo.tbl_Tags.ThumbnailId
FROM dbo.tbl_Tags LEFT OUTER JOIN
dbo.tbl_Thumbnails
ON dbo.tbl_Tags.ThumbnailId = dbo.tbl_Thumbnails.ThumbnailId
GO
INSERT INTO tbl_Tags VALUES ('16b23bb8-bf17-4784-b80a-220da1163584', NULL)
INSERT INTO tbl_Tags VALUES ('e8b50f03-65a9-4d1e-b3b4-268f01645c4e', 'a45e357b-ca9c-449a-aa27-834614eb3f6e')
INSERT INTO tbl_Thumbnails VALUES ('a45e357b-ca9c-449a-aa27-834614eb3f6e', NULL, 150, 150)
Teraz robi następujące wydajności zapytań „Nie można utworzyć indeks na widoku” Test .dbo.v_Tags. „ponieważ używa lewej, prawej lub FULL OUTER JOIN, a brak sprzężenia zewnętrzne są dozwolone w widoków indeksowanych rozważyć użycie zamiast sprzężenia wewnętrznego.”:
CREATE UNIQUE CLUSTERED INDEX [TagId] ON [dbo].[v_Tags]
(
[TagId] ASC
)
GO
To jest oczekiwane zachowanie, ale jaki sposób działania zaleciłbyś uzyskać najlepszą wydajność z mojego scenariusza? Punktem wyjścia do domu jest najlepsza wydajność.
Czego kończy się robi z tym? Mam do czynienia z podobnym problemem, próbując zindeksować niektóre opinie. – user1948635
W podobnej sytuacji, tabela denormalizowana (z wyzwalaczami lub inny sposób jej aktualizacji) może być również opcją na liście. –
Odpowiedziałem na bardzo podobne pytanie dotyczące materializowania indeksów dla lewych złączeń. Chociaż nie ma bezpośredniego sposobu, aby to zrobić ... tutaj jest opcja # 5 http://stackoverflow.com/a/31171129/1902664 – cocogorilla