Объединение псевдо-разделенных таблиц в одно представление

Допустим, у нас есть 5 таблиц

Fact_2011
Fact_2010
Fact_2009
Fact_2008
Fact_2007

каждый из которых хранит только транзакции за год, указанный расширением имени таблицы.

Затем мы создаем отдельный индекс для каждой из этих таблиц со столбцом «Год» в качестве первого столбца индекса.

Наконец, мы создаем представление vwFact, которое представляет собой объединение всех таблиц:

SELECT * FROM Fact_2011
UNION
SELECT * FROM Fact_2010
UNION
SELECT * FROM Fact_2009
UNION
SELECT * FROM Fact_2008
UNION
SELECT * FROM Fact_2007

а затем выполните такие запросы:

SELECT * FROM vwFact WHERE YEAR = 2010

или в менее вероятных ситуациях,

SELECT * FROM vwFact WHERE YEAR > 2010 

Насколько эффективны эти запросы по сравнению с фактическим разделением данных по годам или это по существу одно и то же? Нужен ли индекс Year для каждой из этих псевдосекционированных таблиц, чтобы механизм SQL не тратил более тривиального времени на определение того, что физическая таблица, содержащая записи за пределами искомого диапазона дат, не стоит сканирования? Или этот подход псевдо-разбиения именно то, что делает разбиение MS (по годам)?

Мне кажется, что если запрос выполняется

SELECT Col1Of200 FROM vwFact WHERE YEAR = 2010 

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

Комментарии?


person Chad    schedule 07.10.2011    source источник


Ответы (1)


Я с большим успехом реализовал секционированные представления на SQL Server 2000.

Убедитесь, что у вас есть проверочное ограничение для каждой таблицы, которое ограничивает столбец года годом. Таким образом, в таблице Fact_2010 будет Check Year = 2010.

затем также сделайте представление UNION ALL не только UNION

теперь, когда вы запрашиваете представление в течение одного года, оно должно просто обращаться к 1 таблице, вы можете проверить это с помощью плана выполнения

если у вас нет проверочных ограничений, это коснется всех таблиц, которые являются частью представления.

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

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

person SQLMenace    schedule 07.10.2011
comment
Предполагая, что ваш комментарий «Убедитесь», что он верен (а я ожидаю, что так оно и будет) :-), это отличная информация, которую нужно знать, и для меня это удивительный факт! Последующее размышление: не будет ли представление индекса по ГОДУ над UNION всех таблиц FACT более подходящим, чем отдельный индекс по Году для каждой физической таблицы? Кроме того, хотя UNION ALL является более понятным и лучшим выбором, я не понимаю, как UNION может возвращать разные результаты с учетом ограничения. Комментарии? Большое спасибо за ваш ответ. Я люблю это. - person Chad; 07.10.2011
comment
Индексированное представление должно поддерживаться, поэтому все ваши обновления удаляются и вставляются медленнее. Также вам нужно больше места в вашей БД для хранения этого представления. - person SQLMenace; 07.10.2011
comment
@Chad: Что касается UNION ALL vs UNION, речь идет не о том, будут ли отличаться результаты, а скорее об избавлении от абсолютно ненужной сортировки, которую выполняет UNION (из-за подразумеваемого DISTINCT). - person Andriy M; 07.10.2011