SQL Server има системна съхранена процедура, наречена sp_estimate_data_compression_savings
, което ви позволява да проверявате размера на обекта и неговия приблизителен размер с различни нива на компресия.
Ако обектът вече е компресиран, можете да използвате тази процедура, за да оцените размера му при повторно компресиране.
Обектите могат да бъдат компресирани чрез компресиране на архив на ред, страница, columnstore или columnstore.
Компресията може да бъде оценена за цели таблици или части от таблици. Това включва купища, клъстерирани индекси, неклъстерирани индекси, индекси на columnstore, индексирани изгледи и дялове на таблици и индекси.
Пример
Ето пример за демонстрация.
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemHoldings', @index_id =NULL, @partition_number =NULL, @data_compression ='ROW';
Резултат:
+------------------+--------------+---------- --+-------------------+----------------------------------- ------------------+-------------------------------- -----------------+-------------------------------- --------------------+---------------------------- -------------------------+| име_обект | schema_name | идентификатор_индекс | номер_ на дял | size_with_current_compression_setting(KB) | size_with_requested_compression_setting(KB) | sample_size_with_current_compression_setting(KB) | sample_size_with_requested_compression_setting(KB) ||------------------+--------------+-------- ----+-------------------+----------------------- ---------------------+---------------------------- ------------------+-------------------------------- ---------------------+-------------------- ---------------------------|| StockItem Holdings | Склад | 1 | 1 | 32 | 8 | 40 | 16 |+-------------------+--------------+----------- -+-------------------+-------------------- ------------------+--------------------------------------- ----------------+-------------------------------- ------------------+-------------------------------- ------------------------+
За да ви спести от необходимостта да правите твърде много странично превъртане, тук отново използва вертикално извеждане:
-[ ЗАПИС 1 ]------------------------------ име_на_обект | StockItem Holdingsschema_name | Индекс_на_склад | 1номер_на_раздел | 1size_with_current_compression_setting(KB) | 32size_with_requested_compression_setting(KB) | 8sample_size_with_current_compression_setting(KB) | 40sample_size_with_requested_compression_setting(KB) | 16
Размерите на компресия са в килобайти (KB).
В този случай изглежда има значителна полза от използването на компресиране на редове в тази таблица. Той преминава от 32 KB до 8 KB. Това предполага, че е точна оценка.
Когато изпълних предишния код, предоставих всички имена на аргументи. Можете също да пропуснете тези имена и просто да предоставите стойностите.
Като това:
EXEC sp_estimate_data_compression_savings 'Склад', 'StockItemHoldings', NULL, NULL, 'ROW';
Така или иначе резултатът е същият.
Ето го отново, но този път посочвам PAGE
вместо ROW
като тип компресия.
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemHoldings', @index_id =NULL, @partition_number =NULL, @data_compression ='PAGE';
Резултат (с помощта на вертикален изход):
-[ ЗАПИС 1 ]------------------------------ име_на_обект | StockItem Holdingsschema_name | Индекс_на_склад | 1номер_на_раздел | 1size_with_current_compression_setting(KB) | 32size_with_requested_compression_setting(KB) | 8sample_size_with_current_compression_setting(KB) | 40sample_size_with_requested_compression_setting(KB) | 16
В този случай числата изглеждат еднакви, но можете да получите много различни числа, в зависимост от вашите данни.
Типове компресия
@data_compression
аргументът приема следните стойности:
НЯМА
ROW
СТРАНИЦА
COLUMNSTORE
COLUMNSTORE_ARCHIVE
Това са опциите за компресиране, налични при създаване/промяна на таблица или индекс.
COLUMNSTORE
и COLUMNSTORE_ARCHIVE
опциите са налични само за индекси на columnstore (включително както неклъстерирани индекси columnstore, така и клъстерирани индекси columnstore).
@index_id
Аргумент
Понякога резултатите ви може да върнат няколко реда за даден обект, всеки с различен index_id .
Можете да го стесните до конкретен индекс, ако предпочитате. За да направите това, предоставете index_id към @index_id
аргумент.
Например, когато стартирам следния код, се връщат осем реда, всеки с различен index_id стойности.
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemTransactions', @index_id =NULL, @partition_number =NULL, @data_compression ='ROW';
Резултат:
+-----------------------+--------------+------ ------+--------------------+--------------------- -----------------------+------------------------- ---------------------+---------------------------- ------------------------+-------------------------------- ----------------------------+| име_обект | schema_name | идентификатор_индекс | номер_ на дял | size_with_current_compression_setting(KB) | size_with_requested_compression_setting(KB) | sample_size_with_current_compression_setting(KB) | sample_size_with_requested_compression_setting(KB) ||-----------------------+---------------+---- --------+-------------------+-------------------- -------------------------+----------------------- -----------------------+------------------------- -------------------------+----------------------- -------------------------------|| StockItemTransactions | Склад | 2 | 1 | 5568 | 4120 | 4280 | 3168 || StockItemTransactions | Склад | 3 | 1 | 5184 | 3720 | 4264 | 3064 || StockItemTransactions | Склад | 4 | 1 | 5568 | 4224 | 4288 | 3256 || StockItemTransactions | Склад | 5 | 1 | 5528 | 4416 | 4280 | 3424 || StockItemTransactions | Склад | 6 | 1 | 5192 | 3456 | 4264 | 2840 || StockItemTransactions | Склад | 7 | 1 | 5192 | 3464 | 4264 | 2848 || StockItemTransactions | Склад | 9 | 1 | 5416 | 4456 | 4264 | 3512 || StockItemTransactions | Склад | 1 | 1 | 2720 | 9096 | 2720 | 9096 |+-----------------------+--------------+------- -----+-------------------+----------------------- ---------------------+-------------------- --------------------+---------------------------- -----------------------+------------------------- ----------------------------+
Ако искаме да го стесним само до един ред, бихме могли да използваме неговия index_id .
Като това:
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemTransactions', @index_id =1, @partition_number =NULL, @data_compression ='ROW';
Резултат:
+-----------------------+--------------+------ ------+--------------------+--------------------- -----------------------+------------------------- ---------------------+---------------------------- ------------------------+-------------------------------- ----------------------------+| име_обект | schema_name | идентификатор_индекс | номер_ на дял | size_with_current_compression_setting(KB) | size_with_requested_compression_setting(KB) | sample_size_with_current_compression_setting(KB) | sample_size_with_requested_compression_setting(KB) ||-----------------------+---------------+---- --------+-------------------+-------------------- -------------------------+----------------------- -----------------------+------------------------- -------------------------+----------------------- -------------------------------|| StockItemTransactions | Склад | 1 | 1 | 2720 | 9096 | 2720 | 9096 |+-----------------------+--------------+------- -----+-------------------+----------------------- ---------------------+-------------------- --------------------+---------------------------- -----------------------+------------------------- ----------------------------+
Можете също да използвате @partition_number да направите същото с дяловете.
Размерът на компресия може да варира значително
Размерът на компресия, който получавате, ще зависи от данните и вида на компресията.
ROW
компресията, например, премахва ненужните байтове от стойностите на колоните, като ги съхранява във формат с променлива дължина. PAGE
компресията, от друга страна, съхранява повтарящите се стойности само веднъж на страница и задава показалеца от съответните колони в страницата.
Понякога може да откриете, че компресирането на обект не винаги намалява неговия размер, а в някои случаи всъщност може да увеличи неговия размер.
Това може да се случи, ако вашите колони използват тип данни, който не се възползва от компресия.
Освен това компресирането на ред намалява излишните разходи за метаданни, но в някои случаи служебните разходи може да са по-големи от стария формат за съхранение.
Ако данните ви не получават никаква полза от компресията поради своя тип данни, тогава е вероятно режийните разходи да доведат до увеличаване на изискванията за съхранение, а не до намаляване.
Но вариациите в размера на компресията също ще зависят от действителните данни. Например, ако имате char(10) колона, компресията ще премахне всички последващи знаци за допълване. Ако имате много редове със завършващи знаци за допълване, трябва да получите по-добър резултат, отколкото ако нямате (или малко) редове със завършващи знаци за допълване.
Как оценява компресията?
Когато изпълните sp_estimate_data_compression_savings
, той взема извадка от данните и след това ги зарежда в еквивалентна таблица и индекс, създадени в tempdb . Таблицата или индексът се създават в tempdb след това се компресира до исканата настройка и се изчислява прогнозната икономия на компресия.
Колко е точна?
Може да получите смесени резултати, когато използвате sp_estimate_data_compression_savings
.
Нека направим малък тест.
ИЗБЕРЕТЕ * INTO Warehouse.StockItemTransactions2FROM Warehouse.StockItemTransactions;EXEC sp_spaceused 'Warehouse.StockItemTransactions2';
Резултат (с помощта на вертикален изход):
<предварително име | StockItemTransactions2rows | 236667 запазени | 15944 KB данни | 15800 KBиндекс_размер | 8 KBизползвано | 136 KB
sp_spaceused
Съхранената процедура ни показва действително използваното дисково пространство. В този случай данните използват 15 800 KB дисково пространство.
Сега ще изпълня sp_estimate_data_compression_savings
за да видя какво спестяване на място ще получа, ако приложа компресия към тази таблица.
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemTransactions2', @index_id =NULL, @partition_number =NULL, @data_compression ='ROW';
Резултат (с помощта на вертикален изход):
име_на_обект | StockItemTransactions2schema_name | Индекс_на_склад | 0номер_на_раздел | 1size_with_current_compression_setting(KB) | 15808size_with_requested_compression_setting(KB) | 9096sample_size_with_current_compression_setting(KB) | 15800sample_size_with_requested_compression_setting(KB) | 9096
Според тези резултати, прилагането на компресия на редове към тази таблица ще намали нейния размер от 15 808 KB до прогнозен размер от само 9 096 KB. Не е много лошо.
Нека сега да приложим компресия на редове към тази таблица и след това да изпълним sp_spaceused
отново.
ПРОМЕНЯТ ТАБЛИЦА Warehouse.StockItemTransactions2REBUILD WITH (DATA_COMPRESSION =ROW);EXEC sp_spaceused 'Warehouse.StockItemTransactions2';
Резултат (с помощта на вертикален изход):
<предварително име | StockItemTransactions2rows | 236667 запазени | 9160 KB данни | 9088 KBиндекс_размер | 8 KBТака че действителният резултат е много близък до очаквания резултат.
В този случай sp_estimate_data_compression_savings
предостави доста точна оценка на крайния резултат.
Нека изпълним sp_estimate_data_compression_savings
още веднъж, но използвайки тип компресия NONE
.
EXEC sp_estimate_data_compression_savings @schema_name ='Склад', @object_name ='StockItemTransactions2', @index_id =NULL, @partition_number =NULL, @data_compression ='NONE';
Резултат:
име_на_обект | StockItemTransactions2schema_name | Индекс_на_склад | 0номер_на_раздел | 1size_with_current_compression_setting(KB) | 9096size_with_requested_compression_setting(KB) | 15808sample_size_with_current_compression_setting(KB) | 9096sample_size_with_requested_compression_setting(KB) | 15808
Това ни казва какво би се случило, ако се върнем към без компресия.
В този случай ни показва точно същото число (15 808 KB), което ни показа преди прилагането на компресия, което, както си спомняте, беше доста близо до действителния размер (15 800 KB), върнат от sp_spaceusedкод> процедура.
Така че нека го стартираме отново и да разберем.
ПРОМЕНЯ ТАБЛИЦА Warehouse.StockItemTransactions2REBUILD WITH (DATA_COMPRESSION =NONE);EXEC sp_spaceused 'Warehouse.StockItemTransactions2';
Резултат (с помощта на вертикален изход):
<предварително име | StockItemTransactions2rows | 236667 запазени | 15880 KB данни | 15800 KBиндекс_размер | 8 KBизползвано | 72 KB
И така, отново sp_estimate_data_compression_savings
беше почти на място.
Това обаче е само един прост тест. Други тестове могат да върнат оценки, които са далеч. Чел съм истории за sp_estimate_data_compression_savings
връщам изключително неточни резултати, но аз все още не съм го изпитал.
Следователно изглежда, че sp_estimate_data_compression_savings
може да предостави точна оценка в същите случаи, но не толкова в други.
Ще трябва да решите колко доверие искате да вложите в тази съхранена процедура. Във всеки случай вероятно трябва да изпълните тест във вашата среда за разработка или тестване, преди да приложите компресия в производството.