Вопрос по sql, sql-server-2008, sql-server – Индексированные просмотры и левые соединения раз и навсегда

23

Я использую MSSQL Server 2008 R2 и пытаюсь оптимизировать свои представления, когда наткнулся на индексированные представления. К сожалению, большинство моих видов используют левые внешние соединения, которые не поддерживаются в индексированных представлениях. После нескольких исследований я остался в замешательстве, как лучше всего это сделать. На мой взгляд, у меня есть следующие варианты:

1) Преобразуйте левые объединения во внутренние объединения, используя метод для имитации левого объединения с помощью команды «ИЛИ (IsNull (a) И IsNull (b))» & quot;

Я нашел это решение в нескольких местах, но было упоминание о потере производительности.

2) Преобразуйте левые объединения во внутренние объединения и замените пустые столбцы с пустыми направляющими (00000000-0000-0000-0000-000000000000) и добавьте одну строку в правой таблице с соответствующей направляющей.

Это кажется наиболее очевидным с точки зрения производительности, но кажется пустой тратой пространства для каждой строки, которая в противном случае была бы NULL.

3) Разбейте мой взгляд на два вида. Первое представление - это большая часть моей логики, которая индексируется. И второй вид, вытекающий из первого и добавляющий левые.

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

4) Не индексируйте мои взгляды

Будет ли оставить представление так, как оно будет более производительным, чем любой из вышеперечисленных вариантов?

5) Идея, о которой я не думал

Я написал свой основной сценарий следующим образом:

<code>   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)
</code>

Теперь, выполнив следующий запрос, мы получим & quot; Невозможно создать индекс для представления & quot; Test.dbo.v_Tags & quot; потому что он использует соединение LEFT, RIGHT или FULL OUTER, а соединения OUTER не допускаются в индексированных представлениях. Попробуйте вместо этого использовать INNER join. & Quot ;:

<code>CREATE UNIQUE CLUSTERED INDEX [TagId] ON [dbo].[v_Tags] 
(
[TagId] ASC
)
GO 
</code>

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

Что вы в итоге сделали с этим? Я сталкиваюсь с подобной проблемой, пытаясь проиндексировать некоторые взгляды. user1948635
Я ответил на очень похожий вопрос о материализации индексов на левых соединениях. Хотя прямого способа сделать это не существует ... есть вариант № 5stackoverflow.com/a/31171129/1902664 cocogorilla
Столкнувшись с аналогичной ситуацией, денормализованная таблица (с триггерами или каким-либо другим способом ее обновления) также может быть вариантом в списке. Alex M

Ваш Ответ

1   ответ
7

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

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

Если вы используетеProfiler + ДТА или дажеDMVs вы можете придумать правильные индексы, которые будут созданы в ваших таблицах, которые выиграют от любого представления

в таком случае да. Вы правы
Что если представление представляет почти постоянные данные (редко изменяемые в базовых таблицах) и также используется во многих местах? Индексированное представление очень помогает для производительности в этом случае
Вы также должны проиндексировать свое представление, если вы хотите создать полнотекстовый индекс для него.

Похожие вопросы