Построение индексов – часть 6: построение секционированного индекса (Partitioned Index)

Построение индексов – часть 6: построение секционированного индекса (Partitioned Index)

  • Comments 4
  • Likes

Существуют две основных категории секционированных индексов:

  • Выровненные (когда базовая таблица и индекс используют одинаковые функции секционирования)
  • Невыровненные (когда базовая таблица и индекс используют разные функции секционирования (включая случай, когда базовая таблица вообще не секционирована, а индекс секционирован).

(см. Типы построения индексов - Часть 2 (секционированные индексы)) 

 

 

Построение выровненных секционированных индексов 

 

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

 

     NL

                /       \

             ПТС   Построитель

                           \

                        [Сортировка]

                             \

                          Сканирование

 

ПТС: Постоянный  табличный скан (the purpose of CTS is to provide partition IDs for index builder)

NL: Nested Loop (вложенный цикл)

 

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

 

Как это влияет на требования к свободному дисковому пространству:

-         В случае сортировки в пользовательской базе данных (установка по умолчанию) сортировка происходит в каждой filegroup для каждой соответствующей секции. Это означает, что каждая файловая группа должна иметь те же 2.2*(Размер секции) свободного дискового пространства для того, чтобы можно было построить индекс.

      Пример:

                  Имеются 3 секции расположенные в файловых группах FG1, FG2, FG3. Размер индексных данных (соответственно для каждой секции) – 1Gb, 2Gb и 3Gb. В этом случае потребуется: 2.2*1 = 2.2Gb свободного пространства в FG1; 2.2*2 = 4.4Gb свободного пространства в FG2, 2.2*3 = 6.6Gb свободного пространства в FG3. Таким образом, общий размер свободного дискового пространства, необходимого в этом случае - 9.9Gb.

 

-         В случае сортировки в tempdb (SORT_IN_TEMPDB = ON) свободное пространство в tempdb будет переиспользоваться для сортировки каждой секцию Так как сортировка секций происходит последовательно одна за одной, потребуется только 2.2*(Размер наибольшей секции) свободного дискового пространства в tempdb.

      Пример:

                  Возьмем пример рассмотренный выше: имеются 3 секции расположенные в файловых группах FG1, FG2, FG3. Размер индексных данных (соответственно для каждой секции) – 1Gb, 2Gb и 3Gb. В этом случае потребуется: 3.3Gb свободного дискового пространства в tempdb.

 

Некоторые соображения об использовании памяти:

 Так как в одно и тоже время существует только одна промежуточная структура сортировки, потребуется 40 страниц памяти (необходимая память), чтобы начать построение индекса. 40 страницэто минимальное требование.

Общее объем памяти = минимально требуемая память + дополнительная память*.

 

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

 

Читайте в следующих постах о параллельном построении выровненного секционированного индекса J

Comments
  • Здравствуйте, Людмила!

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

  • Точнее говоря - индексы должны быть идентичными и секционированными с той же функцией, что и сама таблица.

    Дело в том, что сейчас переключение секций из одной таблицы в другую написано, как простая операция над мета данными (данные в системных таблицах sys.partitions, sys.objects и т.д.). Сами данные никуда не перемещаются. Т.е., когда вы говорите переключить секцию 3 из таблицы t1 в таблицу t2, в sys.partitions object_id (соответствующей секции) t1 меняется на object_id t2. Ну, это упрощенно, конечно.

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

    Не знаю, понятно ли я объяснила :).

  • Насколько я понял в SQL Server секционирование - единнственный вариант организации VLDB так ли это?

    Понятно, что при переключении секции затрагиваются только метаданные, но если данные никуда не перемещаются, то зачем перестраивать некластерные индексы в этих двух таблицах, возможно вопрос глупый(трудно вникнуть в организаию некластерных индексов на таком уровне). Он просто интересен вот по какой причине: есть основная секционированная таблица (секционирована по дате), размером 300 ГБ, и есть вспомогательная небольшая секционированная таблица, предназначенная для занесения, допустим месячных данных, как только месяц заканчивается, секция переключается из вспомогательной таблицы в основную. Для этого необходимо снять индексы с обеих таблиц. Пока операция удаления/построения индексов (не PK :-)) в основной таблице занимает около 40 мин, а что будет, когда размер таблицы будет несколько терробайт? И еще, не планируется ли создать какой-нибудь UI для управления секционированными таблицами, например, удаление секций из таблиц или их перемещение между таблицами. Спасибо.

  • Секционирование – рекомендованный вариант. В принципе, есть еще старый вариант построения Представления (View) поверх нескольких таблиц. Ну, и, в конце концов, просто несколько баз данных  - одна рабочая, остальные – архив. Понятно, что это не очень удобно и менее эффективно.

    Почему нельзя в вашем случае переключать секции при наличии несекционированного индекса. Индекс хранится в базе данных как отдельный объект (b-дерево). Если индекс не секционирован, то это одно целое b-дерево. Когда вы переключаете, скажем, секцию 3, из таблицы t1 в таблицу t2, SQL Server просто меняет метаданные этой секции таблицы. А что в этом случае можно сделать с индексом? У него нет секций в вашем варианте. Как его изменить таким образом, чтобы данные соответствующие секции 3 таблицы t1 перенеслись в индекс таблицы t2? Тут уже требуется перестроение всего индекса.

    А зачем вам нужно, чтобы этот некластерный индекс был несекционированным? Это, в общем, весьма неэффективное решение. Если вы сделаете эти индексы секционированными используя ту же функцию секционирования, что и у таблицы , вам не придется их удалять и создавать заново. Вы можете по прежнему держать их в другой файлгруппе, если это критично; вам просто придется создать отдельную схему секционирования для индексов, использующую ту же функцию секционирования, но другие файлгруппы

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment