sql >> Databáze >  >> RDS >> Sqlserver

Odhadněte úspory komprese dat na serveru SQL Server

SQL Server má systémovou uloženou proceduru s názvem sp_estimate_data_compression_savings , která vám umožňuje zkontrolovat velikost objektu a jeho odhadovanou velikost s různými úrovněmi komprese.

Pokud je objekt již zkomprimován, můžete tento postup použít k odhadu jeho velikosti při opětovné komprimaci.

Objekty lze komprimovat pomocí komprese archivu řádků, stránek, sloupců nebo sloupců.

Kompresi lze hodnotit pro celé tabulky nebo části tabulek. To zahrnuje haldy, klastrované indexy, neklastrované indexy, indexy sloupců, indexované pohledy a oddíly tabulek a indexů.

Příklad

Zde je příklad k demonstraci.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemHoldings', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Výsledek:

+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name       | schema_name   | index_id   | partition_number   | 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)   |
|-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------|
| StockItemHoldings | Warehouse     | 1          | 1                  | 32                                          | 8                                             | 40                                                 | 16                                                   |
+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Abyste nemuseli dělat příliš mnoho stranového posouvání, zde je opět použití vertikálního výstupu:

-[ RECORD 1 ]-------------------------
object_name                                        | StockItemHoldings
schema_name                                        | Warehouse
index_id                                           | 1
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 32
size_with_requested_compression_setting(KB)        | 8
sample_size_with_current_compression_setting(KB)   | 40
sample_size_with_requested_compression_setting(KB) | 16

Velikosti komprese jsou v kilobajtech (KB).

V tomto případě se zdá být významnou výhodou použití komprese řádků v této tabulce. Pohybuje se od 32 kB do 8 kB. To předpokládá, že se jedná o přesný odhad.

Když jsem spustil předchozí kód, poskytl jsem všechny názvy argumentů. Tyto názvy můžete také vynechat a zadat pouze hodnoty.

Takhle:

EXEC sp_estimate_data_compression_savings 
    'Warehouse', 
    'StockItemHoldings', 
    NULL, 
    NULL, 
    'ROW';

V každém případě je výsledek stejný.

Tady je to znovu, ale tentokrát specifikuji PAGE místo ROW jako typ komprese.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemHoldings', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'PAGE';

Výsledek (při použití vertikálního výstupu):

-[ RECORD 1 ]-------------------------
object_name                                        | StockItemHoldings
schema_name                                        | Warehouse
index_id                                           | 1
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 32
size_with_requested_compression_setting(KB)        | 8
sample_size_with_current_compression_setting(KB)   | 40
sample_size_with_requested_compression_setting(KB) | 16

V tomto případě čísla vypadají stejně, ale v závislosti na vašich datech můžete získat výrazně odlišná čísla.

Typy komprese

@data_compression argument přijímá následující hodnoty:

  • ŽÁDNÉ
  • ROW
  • PAGE
  • COLUMNSTORE
  • ARCHIV COLUMNSTORE_ARCHIVE

Toto jsou možnosti komprese dostupné při vytváření/změně tabulky nebo indexu.

COLUMNSTORE a ARCHIV COLUMNSTORE volby jsou dostupné pouze u indexů columnstore (včetně indexů neclusterovaných columnstore i klastrovaných columnstore).

@index_id Argument

Někdy mohou výsledky pro daný objekt vrátit několik řádků, každý s jiným index_id .

Pokud chcete, můžete jej zúžit na konkrétní index. Chcete-li to provést, zadejte index_id na @index_id argument.

Když například spustím následující kód, vrátí se osm řádků, každý s jiným index_id hodnoty.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Výsledek:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name           | schema_name   | index_id   | partition_number   | 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 | Warehouse     | 2          | 1                  | 5568                                        | 4120                                          | 4280                                               | 3168                                                 |
| StockItemTransactions | Warehouse     | 3          | 1                  | 5184                                        | 3720                                          | 4264                                               | 3064                                                 |
| StockItemTransactions | Warehouse     | 4          | 1                  | 5568                                        | 4224                                          | 4288                                               | 3256                                                 |
| StockItemTransactions | Warehouse     | 5          | 1                  | 5528                                        | 4416                                          | 4280                                               | 3424                                                 |
| StockItemTransactions | Warehouse     | 6          | 1                  | 5192                                        | 3456                                          | 4264                                               | 2840                                                 |
| StockItemTransactions | Warehouse     | 7          | 1                  | 5192                                        | 3464                                          | 4264                                               | 2848                                                 |
| StockItemTransactions | Warehouse     | 9          | 1                  | 5416                                        | 4456                                          | 4264                                               | 3512                                                 |
| StockItemTransactions | Warehouse     | 1          | 1                  | 2720                                        | 9096                                          | 2720                                               | 9096                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Pokud bychom jej chtěli zúžit pouze na jeden řádek, mohli bychom použít jeho index_id .

Takhle:

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions', 
    @index_id =1, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Výsledek:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name           | schema_name   | index_id   | partition_number   | 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 | Warehouse     | 1          | 1                  | 2720                                        | 9096                                          | 2720                                               | 9096                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Můžete také použít @číslo_oddílu udělat to samé s oddíly.

Množství komprese se může výrazně lišit

Velikost komprese, kterou získáte, bude záviset na datech a typu komprese.

ROW komprese například odstraní nepotřebné bajty z hodnot sloupců jejich uložením ve formátu s proměnnou délkou. STRÁNKA komprese na druhou stranu ukládá opakující se hodnoty pouze jednou na stránku a nastavuje ukazatel z příslušných sloupců na stránce.

Někdy můžete zjistit, že komprimací objektu se ne vždy sníží jeho velikost a v některých případech se může skutečně zvětšit jeho velikost.

K tomu může dojít, pokud vaše sloupce používají datový typ, který nemá prospěch z komprese.

Komprese řádků také snižuje režii metadat, ale v některých případech může být režie větší než u starého formátu úložiště.

Pokud vaše data nemají žádnou výhodu z komprese kvůli jejich datovému typu, pak je pravděpodobné, že režie způsobí spíše zvýšení požadavků na úložiště než snížení.

Ale rozdíly ve velikosti komprese budou také záviset na skutečných datech. Pokud máte například char(10) sloupec, komprese odstraní všechny koncové výplňové znaky. Pokud máte mnoho řádků s koncovými výplňovými znaky, měli byste získat lepší výsledek, než když nemáte žádné (nebo málo) řádky s koncovými výplňovými znaky.

Jak odhaduje kompresi?

Když spustíte sp_estimate_data_compression_savings , vezme vzorek dat a poté je načte do ekvivalentní tabulky a indexu vytvořeného v tempdb . Vytvořte tabulku nebo index v tempdb se poté zkomprimuje na požadované nastavení a vypočítá se odhadovaná úspora komprese.

Jak je to přesné?

Při použití sp_estimate_data_compression_savings můžete získat smíšené výsledky .

Udělejme si malý test.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Výsledek (při použití vertikálního výstupu):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 15944 KB
data       | 15800 KB
index_size | 8 KB
unused     | 136 KB

sp_spaceused uložená procedura nám ukazuje skutečně využité místo na disku. V tomto případě data využívají 15 800 kB místa na disku.

Nyní provedu sp_estimate_data_compression_savings abych viděl, jakou úsporu místa dosáhnu, když na tuto tabulku použiji kompresi.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions2', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Výsledek (při použití vertikálního výstupu):

object_name                                        | StockItemTransactions2
schema_name                                        | Warehouse
index_id                                           | 0
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 15808
size_with_requested_compression_setting(KB)        | 9096
sample_size_with_current_compression_setting(KB)   | 15800
sample_size_with_requested_compression_setting(KB) | 9096

Podle těchto výsledků použití komprese řádků na tuto tabulku zmenší její velikost z 15 808 KB na odhadovanou velikost pouhých 9 096 KB. Není to špatné.

Aplikujme nyní na tuto tabulku kompresi řádků a poté spusťte sp_spaceused znovu.

ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = ROW);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Výsledek (při použití vertikálního výstupu):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 9160 KB
data       | 9088 KB
index_size | 8 KB

Skutečný výsledek je tedy velmi blízký výsledku odhadovanému.

V tomto případě sp_estimate_data_compression_savings poskytl docela přesný odhad konečného výsledku.

Spusťte sp_estimate_data_compression_savings ještě jednou, ale pomocí typu komprese NONE .

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions2', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'NONE';

Výsledek:

object_name                                        | StockItemTransactions2
schema_name                                        | Warehouse
index_id                                           | 0
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 9096
size_with_requested_compression_setting(KB)        | 15808
sample_size_with_current_compression_setting(KB)   | 9096
sample_size_with_requested_compression_setting(KB) | 15808

To nám říká, co by se stalo, kdybychom se vrátili zpět k používání bez komprese.

V tomto případě nám ukazuje přesně stejné číslo (15 808 KB), které nám ukazovalo před použitím komprese, které, jak si jistě vzpomínáte, bylo docela blízko skutečné velikosti (15 800 KB) vrácené sp_spaceused postup.

Pojďme to tedy spustit znovu a zjistit.

ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = NONE);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Výsledek (při použití vertikálního výstupu):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 15880 KB
data       | 15800 KB
index_size | 8 KB
unused     | 72 KB

Takže znovu, sp_estimate_data_compression_savings byl téměř na místě.

Toto je však jen jeden jednoduchý test. Jiné testy by mohly vrátit odhady, které jsou daleko. Četl jsem příběhy o sp_estimate_data_compression_savings vrací velmi nepřesné výsledky, ale to jsem ještě nezažil.

Zdá se tedy, že sp_estimate_data_compression_savings může poskytnout přesný odhad ve stejných případech, a ne tolik v jiných.

Budete se muset rozhodnout, jak moc se chcete této uložené proceduře spolehnout. V každém případě byste pravděpodobně měli před použitím komprese v produkci provést test ve svém vývojovém nebo testovacím prostředí.


  1. SQL Server:jak napodobit dotaz oracle keep dense_rank?

  2. Proaktivní kontroly stavu serveru SQL, část 1:Místo na disku

  3. Export dat ze serveru SQL do Excelu a textového souboru pomocí balíčku SSIS

  4. Přidejte sloupec s výchozí hodnotou do existující tabulky na SQL Server