sql >> Database >  >> RDS >> Sqlserver

Besparingen op gegevenscompressie in SQL Server schatten

SQL Server heeft een door het systeem opgeslagen procedure genaamd sp_estimate_data_compression_savings , waarmee u de grootte van een object en de geschatte grootte kunt controleren met verschillende compressieniveaus.

Als het object al is gecomprimeerd, kunt u deze procedure gebruiken om de grootte te schatten wanneer het opnieuw wordt gecomprimeerd.

Objecten kunnen worden gecomprimeerd met behulp van rij-, pagina-, columnstore- of columnstore-archiefcompressie.

Compressie kan worden geëvalueerd voor hele tabellen of delen van tabellen. Dit omvat heaps, geclusterde indexen, niet-geclusterde indexen, columnstore-indexen, geïndexeerde weergaven en tabel- en indexpartities.

Voorbeeld

Hier is een voorbeeld om te demonstreren.

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

Resultaat:

+-------------------+---------------+---------- --+--------------------+-------------------------- -------------------+------------------------------ -----------------+-------------------------------- --------------------+----------------------------- -------------------------+| objectnaam | schema_name | index_id | partitienummer | 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) ||-------------------+---------------+-------- ----+--------------------+------------------------ ---------------------+---------------------------- -------------------+------------------------------ ----------------------+--------------------------- ---------------------------|| VoorraadartikelHoldings | Magazijn | 1 | 1 | 32 | 8 | 40 | 16 |+-------------------+---------------+----------- -+--------------------+--------------------------- ------------------+------------------------------- ----------------+--------------------------------- -------------------+------------------------------ ------------------------+

Om te voorkomen dat u te veel zijwaarts moet scrollen, is hier nogmaals het gebruik van verticale uitvoer:

-[ RECORD 1 ]-------------------------object_name | StockItemHoldingsschema_name | Warehouseindex_id | 1partitie_nummer | 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

De compressiegroottes zijn in kilobytes (KB).

In dit geval lijkt er een aanzienlijk voordeel te zijn bij het gebruik van rijcompressie in deze tabel. Het gaat van 32 KB tot 8 KB. Dit veronderstelt dat het een nauwkeurige schatting is.

Toen ik de vorige code uitvoerde, heb ik alle argumentnamen opgegeven. U kunt deze namen ook weglaten en alleen de waarden opgeven.

Zoals dit:

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

Het resultaat is hoe dan ook hetzelfde.

Hier is het weer, maar deze keer specificeer ik PAGE in plaats van ROW als het compressietype.

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

Resultaat (met verticale uitvoer):

-[ RECORD 1 ]-------------------------object_name | StockItemHoldingsschema_name | Warehouseindex_id | 1partitie_nummer | 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

In dit geval zien de cijfers er hetzelfde uit, maar u kunt enorm verschillende cijfers krijgen, afhankelijk van uw gegevens.

Compressietypen

De @data_compression argument accepteert de volgende waarden:

  • NONE
  • ROW
  • PAGE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Dit zijn de beschikbare compressie-opties bij het maken/wijzigen van een tabel of index.

De COLUMNSTORE en COLUMNSTORE_ARCHIVE opties zijn alleen beschikbaar voor columnstore-indexen (inclusief zowel niet-geclusterde columnstore- als geclusterde columnstore-indexen).

De @index_id Argument

Soms kunnen uw resultaten meerdere rijen voor een bepaald object retourneren, elk met een andere index_id .

U kunt het desgewenst beperken tot een specifieke index. Geef hiervoor de index_id . op naar de @index_id argument.

Als ik bijvoorbeeld de volgende code uitvoer, worden acht rijen geretourneerd, elk met een andere index_id waarden.

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

Resultaat:

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

Als we het willen beperken tot slechts één rij, kunnen we de index_id . gebruiken .

Zoals dit:

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

Resultaat:

+-----------------------+---------------+------ ------+--------------------+---------------------- -----------------------+-------------------------- ---------------------+---------------------------- ------------------------+------------------------- -----------------------------+| objectnaam | schema_name | index_id | partitienummer | 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) ||-----------------------+---------------+---- --------+--------------------+-------------------- -------------------------+------------------------ -----------------------+-------------------------- --------------------------+----------------------- -------------------------------|| Voorraadartikeltransacties | Magazijn | 1 | 1 | 2720 ​​| 9096 | 2720 ​​| 9096 |+-----------------------+---------------+------- -----+--------------------+----------------------- ----------------------+--------------------------- --------------------+----------------------------- -----------------------+-------------------------- ----------------------------+

U kunt ook @partition_number . gebruiken om hetzelfde te doen met partities.

De hoeveelheid compressie kan aanzienlijk variëren

De hoeveelheid compressie die u krijgt, hangt af van de gegevens en het type compressie.

ROW compressie verwijdert bijvoorbeeld onnodige bytes uit de kolomwaarden door ze op te slaan in een formaat met variabele lengte. PAGE compressie daarentegen slaat de herhalende waarden slechts één keer per pagina op en stelt de aanwijzer van de respectieve kolommen op de pagina in.

Soms merkt u misschien dat het comprimeren van een object niet altijd de grootte ervan verkleint, en in sommige gevallen zelfs vergroot zijn grootte.

Dit kan gebeuren als uw kolommen een gegevenstype gebruiken dat niet profiteert van compressie.

Rijcompressie vermindert ook de overhead van metagegevens, maar in sommige gevallen kan de overhead groter zijn dan het oude opslagformaat.

Als uw gegevens vanwege het gegevenstype geen baat hebben bij compressie, is de kans groot dat de overhead een toename van de opslagvereisten veroorzaakt in plaats van een afname.

Maar variaties in compressiegrootte zijn ook afhankelijk van de feitelijke gegevens. Als u bijvoorbeeld een char(10) kolom, zal compressie alle achterliggende opvultekens verwijderen. Als je veel rijen met opvultekens achteraan hebt, zou je een beter resultaat moeten krijgen dan wanneer je geen (of weinig) rijen hebt met opvultekens achteraan.

Hoe schat het de compressie?

Wanneer u sp_estimate_data_compression_savings . uitvoert , het neemt een steekproef van de gegevens en laadt het vervolgens in een equivalente tabel en index gemaakt in tempdb . De tabel of index die is gemaakt in tempdb wordt vervolgens gecomprimeerd tot de gevraagde instelling en de geschatte compressiebesparing wordt berekend.

Hoe nauwkeurig is het?

U kunt gemengde resultaten krijgen bij het gebruik van sp_estimate_data_compression_savings .

Laten we een kleine test doen.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultaat (met verticale uitvoer):

naam | VoorraadArtikelTransacties2rijen | 236667 gereserveerd | 15944 KBgegevens | 15800 KBindex_grootte | 8 KBongebruikt | 136 KB

De sp_spaceused opgeslagen procedure toont ons de werkelijk gebruikte schijfruimte. In dit geval gebruiken gegevens 15.800 KB schijfruimte.

Nu zal ik sp_estimate_data_compression_savings . uitvoeren om te zien welke ruimtebesparing ik krijg als ik compressie toepas op die tabel.

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

Resultaat (met verticale uitvoer):

object_name | StockItemTransactions2schema_name | Warehouseindex_id | 0partitienummer | 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

Volgens deze resultaten zal het toepassen van rijcompressie op deze tabel de grootte verminderen van 15.808 KB tot een geschatte grootte van slechts 9.096 KB. Niet slecht.

Laten we nu rijcompressie toepassen op deze tabel en vervolgens sp_spaceused uitvoeren nogmaals.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultaat (met verticale uitvoer):

naam | VoorraadArtikelTransacties2rijen | 236667 gereserveerd | 9160 KBgegevens | 9088 KBindex_size | 8 KB

Het werkelijke resultaat ligt dus heel dicht bij het geschatte resultaat.

In dit geval sp_estimate_data_compression_savings gaf een vrij nauwkeurige inschatting van het eindresultaat.

Laten we sp_estimate_data_compression_savings uitvoeren nog een keer, maar met het compressietype NONE .

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

Resultaat:

object_name | StockItemTransactions2schema_name | Warehouseindex_id | 0partitienummer | 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

Dit vertelt ons wat er zou gebeuren als we terug zouden gaan naar het gebruik van geen compressie.

In dit geval toont het ons precies hetzelfde aantal (15.808 KB) dat het ons liet zien voordat compressie werd toegepast, wat, zoals u zich zult herinneren, vrij dicht bij de werkelijke grootte (15.800 KB) lag die werd geretourneerd door de sp_spaceused procedure.

Dus laten we het opnieuw doen en erachter komen.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultaat (met verticale uitvoer):

naam | VoorraadArtikelTransacties2rijen | 236667 gereserveerd | 15880 KBgegevens | 15800 KBindex_grootte | 8 KBongebruikt | 72 KB

Dus nogmaals, sp_estimate_data_compression_savings was bijna perfect.

Dit is echter slechts een eenvoudige test. Andere tests kunnen schattingen opleveren die ver weg zijn. Ik heb verhalen gelezen over sp_estimate_data_compression_savings geeft enorm onnauwkeurige resultaten, maar dat moet ik zelf nog ervaren.

Daarom lijkt het erop dat sp_estimate_data_compression_savings kan een nauwkeurige schatting geven in dezelfde gevallen, en niet zozeer in andere.

U moet beslissen hoeveel vertrouwen u in deze opgeslagen procedure wilt stellen. In ieder geval moet u waarschijnlijk een test uitvoeren in uw ontwikkel- of testomgeving voordat u compressie in productie toepast.


  1. GWFG in Oracle RAC

  2. Cloud Vendor Deep-Dive:PostgreSQL op DigitalOcean

  3. Haal de naam van een kolom uit de ID in SQL Server:COL_NAME()

  4. Foutcode:1005. Kan tabel '...' niet maken (fout:150)