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


?????????? ??? ???????? ????????? ???????????????? ????????:



  • ??????????? (????? ??????? ??????? ? ?????? ?????????? ?????????? ??????? ???????????????)

  • ????????????? (????? ??????? ??????? ? ?????? ?????????? ?????? ??????? ??????????????? (??????? ??????, ????? ??????? ??????? ?????? ?? ??????????????, ? ?????? ?????????????).

(??. ???? ?????????? ???????? – ????? 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 (4)

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

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

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

  2. Anonymous says:

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

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

  3. Anonymous says:

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

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

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

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

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

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