Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Изчислете спестяванията при компресиране на данни в SQL Server

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 може да предостави точна оценка в същите случаи, но не толкова в други.

Ще трябва да решите колко доверие искате да вложите в тази съхранена процедура. Във всеки случай вероятно трябва да изпълните тест във вашата среда за разработка или тестване, преди да приложите компресия в производството.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server, подвеждащият XLOCK и оптимизации

  2. Възможни ли са GUID сблъсъци?

  3. Как да ПРОМЕНЯ параметъра на стойността на таблицата

  4. Вземете текущата часова зона на сървъра в SQL Server (T-SQL)

  5. Как да отпечатате VARCHAR(MAX) с помощта на Print Statement?