Подтвердить что ты не робот

Индексированные виды и левые соединения раз и навсегда

Я использую 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 

Это ожидаемое поведение, но какой курс действий вы бы рекомендовали получить наилучшую производительность из моего сценария? Лучшим показателем является лучший результат.

4b9b3361

Ответ 1

Почему вы индексируете свои взгляды? Вы упоминали "трату пространства" в своем решении 2, но знаете ли вы, что, когда вы индексируете свое мнение, вы сохраняете его в БД?

Другими словами, вы делаете копию данных, которые будет возвращаться в БД, и каждый раз, когда данные обновляются в исходных таблицах, некоторый внутренний механизм SQL Server должен обновлять его в этой новой структуре данных, созданной, потому что теперь SQL-сервер больше читает из представления, а не таблицы.

Если вы используете Profiler + DTA или даже DMVS вы можете придумать правильные индексы, которые будут созданы в ваших таблицах, что любое представление будет полезно из