Я использую MSSQL Server 2008 R2, и я пытаюсь оптимизировать свои представления, когда наткнулся на индексированные представления. К сожалению, большинство моих просмотров использует левое внешнее соединение, которое не поддерживается индексированными представлениями. После нескольких исследований я оставил смущенный лучший способ этого. Как я вижу это, у меня есть следующие варианты:
1) Преобразуйте левые соединения во внутренние соединения, используя трюк, чтобы имитировать левое соединение с помощью "OR (IsNull (a) AND IsNull (b))"
Я нашел это решение в нескольких местах, но было упомянуто о потере производительности.
2) Преобразуйте левые соединения во внутренние соединения и замените нулевые значения null null пустыми путями (00000000-0000-0000-0000-000000000000) и добавьте одну строку в правую таблицу с помощью сопоставив guid.
Это кажется наиболее очевидным по производительности, но это кажется пустой тратой пространства для каждой строки, которая в противном случае была бы NULL.
3) Разделите мой взгляд на два вида. Первая точка зрения - это большая часть моей логики, которая является индексируемой. И второе представление, вытекающее из первого вида и добавляющее левые соединения.
Идея здесь заключается в том, что при индексировании базового представления может быть усиление производительности. И то, что даже запрос на производное представление получит хотя бы часть преимуществ производительности.
4) Не индексируйте мои представления
Оставил бы представление так, как он будет более результативным, чем любой из вышеперечисленных вариантов?
5) Идея, о которой я не думал
Я выполнил свой основной сценарий следующим образом:
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)
Теперь, выполнив следующий запрос, вы получите "Невозможно создать индекс в представлении" Test.dbo.v_Tags ", потому что он использует соединение LEFT, RIGHT или FULL OUTER, и в индексированных представлениях не допускаются объединения OUTER. Рассмотрим использование INNER join вместо.":
CREATE UNIQUE CLUSTERED INDEX [TagId] ON [dbo].[v_Tags]
(
[TagId] ASC
)
GO
Это ожидаемое поведение, но какой курс действий вы бы рекомендовали получить наилучшую производительность из моего сценария? Лучшим показателем является лучший результат.