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í.