Использование секционированных представлений

Секционированные представления позволяют разделить данные из большой таблицы на несколько таблиц-элементов меньшего размера. Данные распределяются по секциям между таблицами-элементами в зависимости от значений, содержащихся в одном из столбцов. Диапазоны данных для каждой из таблиц-элементов определяются в ограничении CHECK, устанавливаемом для столбца, по которому выполняется секционирование. Затем определяется представление, использующее инструкцию UNION ALL для объединения выборок из всех таблиц-элементов в единый результирующий набор. Когда инструкция SELECT, ссылающаяся на представление, содержит условие поиска по столбцу секционирования, оптимизатор запросов использует определение ограничений CHECK, чтобы определить, какие из таблиц-элементов содержат соответствующие запросу строки.

ПримечаниеПримечание

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

Например, таблица, содержащая сведения о продажах за 1998 год, секционирована на 12 таблиц-элементов, по одной на каждый месяц. Каждая таблица-элемент содержит ограничение по столбцу OrderMonth (месяц заказа):

CREATE TABLE May1998sales
   (OrderID      INT,
   CustomerID      INT      NOT NULL,
   OrderDate      DATETIME      NULL
      CHECK (DATEPART(yy, OrderDate) = 1998),
   OrderMonth      INT
      CHECK (OrderMonth = 5),
   DeliveryDate      DATETIME      NULL
      CHECK(DATEPART(mm, DeliveryDate) = 5)
   CONSTRAINT OrderIDMonth PRIMARY KEY(OrderID, OrderMonth)
   )

Приложение, заполняющее таблицу May1998sales данными, должно гарантировать, что все строки содержат значение 5 в столбце OrderMonth, то есть дата заказа относится к маю 1998 года. Это требование определяется ограничениями таблицы.

Затем определяется представление с инструкцией UNION ALL, которое служит для выборки данных из всех 12 таблиц-элементов в единый результирующий набор:

CREATE VIEW Year1998Sales
AS
SELECT * FROM Jan1998Sales
UNION ALL
SELECT * FROM Feb1998Sales
UNION ALL
SELECT * FROM Mar1998Sales
UNION ALL
SELECT * FROM Apr1998Sales
UNION ALL
SELECT * FROM May1998Sales
UNION ALL
SELECT * FROM Jun1998Sales
UNION ALL
SELECT * FROM Jul1998Sales
UNION ALL
SELECT * FROM Aug1998Sales
UNION ALL
SELECT * FROM Sep1998Sales
UNION ALL
SELECT * FROM Oct1998Sales
UNION ALL
SELECT * FROM Nov1998Sales
UNION ALL
SELECT * FROM Dec1998Sales

Например, следующая инструкция SELECT запрашивает сведения за определенные месяцы:

SELECT *
FROM Year1998Sales
WHERE OrderMonth IN (5,6) AND CustomerID = 64892

Оптимизатор запросов SQL Server определяет, что условие поиска в инструкции SELECT ссылается только на строки в таблицы May1998Sales и Jun1998Sales. Поэтому он ограничивает область выполнения поиска этими таблицами.

Для выполнения обновлений в секционированном представлении столбец секционирования должен входить в первичный ключ базовой таблицы. Если представление не является обновляемым, можно создать для него триггер типа INSTEAD OF, который будет выполнять обновления. При этом необходимо включить в триггер обработку ошибок, чтобы гарантировать, что в таблицу не будут вставляться повторяющиеся строки. Пример триггера INSTEAD OF для представления см. в разделе Конструирование триггеров INSTEAD OF.

Чтобы секционированное представление возвращало верные результаты, ограничения CHECK не нужны. Однако если ограничения CHECK не определены, оптимизатор запросов будет вынужден выполнять поиск по всем таблицам, а не только по тем, которые соответствуют условию поиска по столбцу секционирования. Без ограничений CHECK представление будет функционировать как любое другое представление, созданное с использованием UNION ALL. Оптимизатор запросов не в состоянии делать предположения о диапазонах значений, хранящихся в различных таблицах, поэтому он не может исключить из поиска ни одну из таблиц, входящих в определение представления.

Если все таблицы-элементы, на которые ссылается секционированное представление, находятся на одном сервере, представление называется локальным секционированным представлением. Если же таблицы-элементы расположены на нескольких серверах, представление называется распределенным секционированным представлением. Распределенные секционированные представления могут использоваться для распределения системной нагрузки при обработке запросов к базе данных между несколькими серверами. Дополнительные сведения см. в разделе Федеративные серверы баз данных.

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

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

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

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

ПримечаниеПримечание

Массовый импорт в секционированное представление не поддерживается ни командой bcp, ни инструкциями BULK INSERT и INSERT ... SELECT * FROM OPENROWSET(BULK...). Однако можно вставить в секционированное представление несколько строк с помощью инструкции INSERT.