Материализованные представления в SQL Server

Материализованное представление — физический объект базы данных, содержащий результат выполнения запроса (Википедия).

Так как в материализованных представлениях хранятся уже заранее вычисленные результаты запроса, включая итоги и результаты соединений таблиц (JOIN). Поэтому получение данных из них выполняет значительно быстрее, чем в случае обычных представлений.

В Oracle уже имеется штатный механизм для создания материализованных представлений на уровне языка PL/SQL (CREATE MATERIALIZED VIEW ). В Transact-SQL, который используется в SQL Server, такого механизма нет, но это не означает, что создать материализованное представление в этой СУБД невозможно.

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

В случае SQL Server этого можно добиться путём создания для представления кластеризованного индекса. Тогда результаты будут сохраняться физически в индексе и и время обращения к ним уменьшится.

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

CREATE VIEW [dbo].[vUsers]
AS
SELECT a.[id],a.[Login],a.[FIO],b.[id] AS RoleId, b.[UserRole] ,a.[Ban] FROM [dbo].[Users] AS a
INNER JOIN [dbo].[UserRoles] AS b ON a.[Role]=b.[id];

Превратим это обычное представление в материализованное.

В начале необходимо привязать представление к схеме при помощи оператора WITH SCHEMABINDING. Без этого создать индекс будет невозможно.

ALTER VIEW [dbo].[vUsers] WITH SCHEMABINDING
AS
SELECT a.[id],a.[Login],a.[FIO],b.[id] AS RoleId, b.[UserRole] ,a.[Ban] FROM [dbo].[Users] AS a
INNER JOIN [dbo].[UserRoles] AS b ON a.[Role]=b.[id];

Привязать представление к схеме можно и при его создании.

CREATE VIEW [dbo].[vUsers] WITH SCHEMABINDING
AS
SELECT a.[id],a.[Login],a.[FIO],b.[id] AS RoleId, b.[UserRole] ,a.[Ban] FROM [dbo].[Users] AS a
INNER JOIN [dbo].[UserRoles] AS b ON a.[Role]=b.[id];

Но в данном примере мы работаем с уже существующим представлением.

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

Ниже приведён пример создания стандартного кластеризованного индекса для представления.

CREATE UNIQUE CLUSTERED INDEX [Index_vUsers] ON [dbo].[vUsers]
(
    [id] ASC,
    [Login] ASC,
    [RoleId] ASC,
    [UserRole] ASC,
    [Ban] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

После создания такого индекса все результаты выполнения запроса в представления будут физически сохраняться в таблице индекса и оно будет работать как материализованное.

Комментарии
  1. А как правильно обновлять данные в таком представлении?

  2. Павел, данные в таком представлении обновляются автоматически при изменении данных в таблицах, на которых оно основано. При этом индекс не перестраивается полностью каждый раз при изменении данных, а дополняется или модифицируется.

  3. Есть ограничения: 1. Warning! The maximum key length for a clustered index is 900 bytes. The index ‘xxx’ has maximum length of 4230 bytes. For some combination of large values, the insert/update operation will fail. 2. Cannot create index on view ‘xxx’ because it contains one or more UNION, INTERSECT, or EXCEPT operators. Consider creating a separate indexed view for each query that is an input to the UNION, INTERSECT, or EXCEPT operators of the original view.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *