SQL Server 2014 CTP1 въвежда разширения за опциите за онлайн работа, което ще бъде добра новина за компаниите, хостващи много големи бази данни, които изискват малко или никакво престой.
За да зададете контекста, представете си, че използвате SQL Server 2012 Enterprise Edition за функциите за онлайн управление на индекси и разделяне на индекси и се опитвате да изградите следния индекс върху разделена таблица:
ALTER INDEX [PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber] ON [dbo].[FactInternetSales] REBUILD PARTITION = ALL WITH (ONLINE= ON);
Тествайки това в SQL Server 2012, ние сме в състояние да възстановим всички дялове онлайн без грешка. Но какво ще стане, ако искаме да посочим конкретен дял вместо всички дялове?
ALTER INDEX [PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber] ON [dbo].[FactInternetSales] REBUILD PARTITION = 1 WITH (ONLINE= ON);
При опит за това в SQL Server 2012 или по-стара версия, ще видите следното съобщение за грешка:
Msg 155, Level 15, State 1, Line 4'ONLINE' не е разпозната опция ALTER INDEX REBUILD PARTITION.
Но като се започне от SQL Server 2014 (от CTP1), вече се поддържат онлайн операции с индекс на един дял. И това със сигурност е голяма работа за много големи сценарии за поддръжка на маса, където бихте предпочели или наистина трябва да разбиете цялостната си поддръжка на по-малки парчета за определен период от време. Може също да искате да направите поддръжка на ниво дял само за онези дялове, които действително го изискват – например тези дялове, които действително надвишават определено ниво на фрагментация.
За да тествам тази функционалност на SQL Server 2014 CTP1, използвах AdventureWorksDW2012 с версия на FactInternetSales, която съдържа 61 847 552 реда и разделена от колоната ShipDate.
Възстановяване на всички дялове онлайн за таблицата с помощта на PARTITION = ALL
в моята тестова среда отне 3 минути и 23 секунди. По отношение на общата продължителност, моите тестове бяха за индекси, които не бяха толкова фрагментирани, така че продължителността от 3 минути и 23 секунди представлява средна продължителност за няколко теста. Също така имайте предвид, че по това време не съм имал конкурентни работни натоварвания, така че онлайн възстановяването се случва, без да се налага да се конкурира с други значителни натоварвания срещу въпросния индекс.
Формата на плана за изпълнение на заявката за повторното изграждане на онлайн индекс с помощта на PARTITION = ALL
беше както следва:
План за изпълнение за онлайн възстановяване на всички дялове
Забележете, че операциите са активирани паралелно, с изключение на оператора Constant Scan. В плана за изпълнение на заявката можете да видите 39 реда във външната справка Constant Scan, които се предават на оператора Distribute Streams и след това управляват вложения цикъл.
Значението на 39-те реда? Следната заявка потвърждава максималния брой на дяловете от sys.dm_db_partition_stats
. За моята тестова среда резултатът беше 39 за максималния номер на дял, съвпадащ с това, което видях за действителните редове на Constant Scan:
SELECT MAX([partition_number]) AS [max_partition_number] FROM [sys].[dm_db_partition_stats] WHERE [object_id] = OBJECT_ID('FactInternetSales');
Сега ще забележите и оператора за вмъкване на онлайн индекс в предишния план. Премахване на ONLINE = ON
опция от моя ALTER INDEX REBUILD
(като го прави офлайн операция) и запазване на PARTITION = ALL
опция, единствената промяна беше да има оператор „Index Insert“ вместо „Online Index Insert“ в плана за изпълнение на заявката – и също така намаляване на продължителността, където моят тест показа продължителност на изпълнение от 1 минута и 9 секунди в сравнение с онлайн 3 минути и 23 секунди.
След това тествах онлайн повторно изграждане на един дял с 5 678 080 реда в него (не забравяйте, че общият брой редове в таблицата е 61 847 552 реда). За този тест общата продължителност отне точно 1 минута и имаше следната форма на план за изпълнение на заявката:
План за изпълнение за онлайн повторно изграждане на един дял
Първото наблюдение е, че това е сериен план. Също така имайте предвид, че казах, че съм избрал един дял от оригиналните 39, въпреки че този конкретен дял представлява ~ 9% от редовете в таблицата като цяло. Също така забележете, че постоянното сканиране показва 1 ред вместо 39, както бих очаквал.
Какво ще кажете за продължителността на един дял, офлайн повторно изграждане? В моята тестова среда това отне 11 секунди в сравнение с онлайн възстановяването за 1 минута. Формата на плана за изпълнение на заявката за офлайн повторното изграждане на единичен дял беше както следва:
План за изпълнение за офлайн повторно изграждане на единичен дял
Забележете, че няма постоянно сканиране или свързан процес на вложени цикли и също така забележете, че този план вече има паралелни оператори в него спрямо предишния сериен план, въпреки че и двамата правят клъстерирано индексно сканиране за 5 678 080 реда. Също така търсенето по ключова дума на „partition“ в текста на XML плана за операцията с паралелен индекс на единичен дял офлайн не доведе до съвпадения – в сравнение със серийния план, онлайн операция с индекс на един дял, която имаше Partitioned =„true“ за Групирано индексно сканиране и онлайн индекс Вмъкване на физически оператори.
Обратно към основното изследване...
Мога ли да избера няколко, но не всички дялове в едно изпълнение? За съжаление не.
ALTER INDEX
и ALTER TABLE
командите имат PARTITION = ALL
аргумент и след това PARTITION = <partition number>
аргумент, но не и възможността за изброяване на множество дялове за една операция за възстановяване. Въпреки това не се оплаквам твърде силно от това, тъй като се радвам, че имам възможността да възстановя единичен дял онлайн и не е много сложно да се изпълни операцията веднъж за всяко възстановяване, но кумулативното въздействие върху продължителността беше нещо Исках да проуча допълнително.
Колко време ще отнеме повторното изграждане на всички 39 дяла поотделно и онлайн спрямо PARTITION = ALL
продължителност 3 минути и 23 секунди?
Знаем, че предимството на онлайн повторното изграждане е възможността все още да има достъп до свързаната таблица или индекс по време на операцията с индекс. Но в замяна на тази онлайн операция, ние ще загубим предимството на производителността на възстановяването в сравнение с офлайн повторното изграждане. И това, което исках да знам по-нататък, беше как ще се представи едно по едно онлайн възстановяване на дял срещу PARTITION = ALL
алтернатива.
Изпълнявайки 39 отделни операции за възстановяване (по едно повторно изграждане за всеки уникален дял), общата продължителност на изпълнение беше 9 минути и 54 секунди в сравнение с PARTITION = ALL
което отне 3 минути и 23 секунди, така че очевидно подходът на парче не е кумулативно толкова бърз, колкото онлайн възстановяването на всички дялове в едно изявление. Въпреки че успях да правя един дял наведнъж, всеобхватното предимство е възможността да разделим нашите дейности по поддръжка с течение на времето и да запазим достъпа до обектите, докато те се възстановяват, но ако търсите по-кратко възстановяване прозорец, офлайн опциите все още са най-бързи, следвани от онлайн за PARTITION = ALL
и след това на последно място, правейки един по един дял.
Следващата таблица обобщава сравненията на продължителността – и отново тези тестове се базираха на SQL Server 2014 CTP1 и много специфичен размер на таблицата и конфигурация на гост на VM, така че обърнете повече внимание на относителните продължителности в тестовете, а не на самите продължителности:
Описание на теста | Продължителност |
---|---|
Офлайн възстановяване на всички дялове | 1:09 |
Онлайн възстановяване на всички дялове | 3:23 |
Онлайн възстановяване на един дял | 1:00 |
Офлайн повторно изграждане на един дял | 0:11 |
Онлайн повторно изграждане на всички дялове, един дял в даден момент | 9:54 |
Сега има и други аспекти, които да проучите по този въпрос. Само защото една операция е онлайн, не означава, че няма няколко момента (или по-дълго), в които все още се задържат ключалки върху целевия обект. Индексните операции все още имат поведение на заключване за онлайн операции – и SQL Server 2014 предостави опции и за това, които ще разгледам в отделна публикация.