sql >> Database teknologi >  >> RDS >> Sqlserver

Estimer datakomprimeringsbesparelser i SQL Server

SQL Server har en systemlagret procedure kaldet sp_estimate_data_compression_savings , som giver dig mulighed for at kontrollere et objekts størrelse og dets estimerede størrelse med forskellige niveauer af komprimering.

Hvis objektet allerede er komprimeret, kan du bruge denne procedure til at estimere dets størrelse, når det genkomprimeres.

Objekter kan komprimeres ved at bruge række-, side-, columnstore- eller columnstore-arkivkomprimering.

Kompression kan evalueres for hele tabeller eller dele af tabeller. Dette inkluderer dynger, klyngede indekser, ikke-klyngede indekser, kolonnelagerindekser, indekserede visninger og tabel- og indekspartitioner.

Eksempel

Her er et eksempel til at demonstrere.

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

Resultat:

+--------------------+--------------+-------- --+--------------------+-------------------------------- --------------+--------------------------------- ------------------+-------------------------------- --------------------+------------------------------------- --------------------------+| objektnavn | skemanavn | index_id | partitionsnummer | 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) ||-------------------+---------------+-------- ----+--------------------+------------------------ --------------------+----------------------------- --------------+--------------------------------- ----------------------+---------------------------- --------------------------|| Lagervarebeholdning | Lager | 1 | 1 | 32 | 8 | 40 | 16 |+--------------------+------------------ --+--------------------+-------------------------------- ------------------+------------------------------- ----------------+--------------------------------- --------------+--------------------------------- ------------------------+

For at spare dig for at skulle lave for meget sidelæns scrollning, her bruger den igen lodret output:

-[ OPTAG 1 ]-------------------------objektnavn | StockItemHoldingsschema_name | Warehouseindex_id | 1partitionsnummer | 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

Kompressionsstørrelserne er i kilobytes (KB).

I dette tilfælde ser der ud til at være en betydelig fordel ved at bruge rækkekomprimering på denne tabel. Det går fra 32 KB til 8 KB. Dette forudsætter, at det er et nøjagtigt skøn.

Da jeg kørte den forrige kode, angav jeg alle argumentnavne. Du kan også udelade disse navne og blot angive værdierne.

Sådan:

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

Uanset hvad, er resultatet det samme.

Her er det igen, men denne gang angiver jeg PAGE i stedet for ROW som komprimeringstype.

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

Resultat (ved hjælp af lodret output):

-[ OPTAG 1 ]-------------------------objektnavn | StockItemHoldingsschema_name | Warehouseindex_id | 1partitionsnummer | 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

I dette tilfælde ser tallene ens ud, men du kan få vidt forskellige tal, afhængigt af dine data.

Kompressionstyper

@data_compression argument accepterer følgende værdier:

  • INGEN
  • RÆKKE
  • SIDE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Disse er de tilgængelige komprimeringsmuligheder, når du opretter/ændrer en tabel eller et indeks.

COLUMNSTORE og COLUMNSTORE_ARCHIVE indstillinger er kun tilgængelige på kolonnelagerindekser (inklusive både ikke-klyngede kolonnelager og klyngede kolonnelagerindekser).

@index_id Argument

Nogle gange returnerer dine resultater muligvis flere rækker for et givet objekt, hver med et forskelligt index_id .

Du kan indsnævre det til et bestemt indeks, hvis du foretrækker det. For at gøre dette skal du angive index_id til @index_id argument.

For eksempel, når jeg kører følgende kode, returneres otte rækker, hver med forskellig indeks_id værdier.

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

Resultat:

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

Hvis vi ville indsnævre den til kun én række, kunne vi bruge dens index_id .

Sådan:

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

Resultat:

+------------------------+------------------ ------+---------------------+---------------------- -----------------------+-------------------------------- --------------------+----------------------------- --------------------+------------------------- ----------------------------+| objektnavn | skemanavn | index_id | partitionsnummer | 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) ||-----------------------------+---------------+---- ----------------------------+--------------------- --------------------------+------------------------ -----------------------+-------------------------------- --------------------------+----------------------- -------------------------------|| Lagervaretransaktioner | Lager | 1 | 1 | 2720 ​​| 9096 | 2720 ​​| 9096 |+-----------------------+---------------- -----+---------------------+------------------------ ----------------------+---------------------------- --------------------+------------------------------------- -----------------------+-------------------------------- ----------------------------+

Du kan også bruge @partition_number at gøre det samme med partitioner.

Mængden af ​​kompression kan variere betydeligt

Mængden af ​​komprimering, du får, afhænger af dataene og typen af ​​komprimering.

ROW komprimering fjerner for eksempel unødvendige bytes fra kolonneværdierne ved at gemme dem i format med variabel længde. SIDE komprimering på den anden side gemmer de gentagne værdier kun én gang pr. side og indstiller markøren fra de respektive kolonner på siden.

Nogle gange vil du måske opdage, at komprimering af et objekt ikke altid reducerer dets størrelse, og i nogle tilfælde kan det faktisk øge dens størrelse.

Dette kan ske, hvis dine kolonner bruger en datatype, der ikke har gavn af komprimering.

Rækkekomprimering reducerer også metadataoverhead, men i nogle tilfælde kan overheaden være større end det gamle lagerformat.

Hvis dine data ikke får nogen fordel af komprimering på grund af dens datatype, er det sandsynligt, at overhead vil medføre en stigning i lagerkravene snarere end et fald.

Men variationer i kompressionsstørrelse vil også afhænge af de faktiske data. For eksempel, hvis du har en char(10) kolonne, vil komprimering fjerne eventuelle efterfølgende udfyldningstegn. Hvis du har mange rækker med efterstillede udfyldningstegn, bør du få et bedre resultat, end hvis du ikke har nogen (eller få) rækker med efterstillede polstringstegn.

Hvordan estimerer den kompressionen?

Når du udfører sp_estimate_data_compression_savings , tager den en prøve af dataene og indlæser dem derefter i en tilsvarende tabel og et tilsvarende indeks oprettet i tempdb . Tabellen eller indekset oprettes i tempdb komprimeres derefter til den ønskede indstilling, og den anslåede komprimeringsbesparelse beregnes.

Hvor nøjagtig er den?

Du kan få blandede resultater, når du bruger sp_estimate_data_compression_savings .

Lad os køre en lille test.

VÆLG * INTO Warehouse.StockItemTransactions2FROM Warehouse.StockItemTransactions;EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultat (ved hjælp af lodret output):

navn | StockItemTransactions2rows | 236667 reserveret | 15944 KBdata | 15800 KBindex_size | 8 KBubrugt | 136 KB

sp_spaceused lagret procedure viser os den faktiske brugte diskplads. I dette tilfælde bruger data 15.800 KB diskplads.

Nu vil jeg udføre sp_estimate_data_compression_savings for at se, hvilke pladsbesparelser jeg får, hvis jeg anvender komprimering på den tabel.

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

Resultat (ved hjælp af lodret output):

objektnavn | StockItemTransactions2schema_name | Warehouseindex_id | 0partitionsnummer | 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

Ifølge disse resultater vil anvendelse af rækkekomprimering på denne tabel reducere dens størrelse fra 15.808 KB til en anslået størrelse på kun 9.096 KB. Ikke så dårligt.

Lad os nu anvende rækkekomprimering på denne tabel og derefter køre sp_spaceused igen.

ALTER TABLE Warehouse.StockItemTransactions2REBUILD WITH (DATA_COMPRESSION =ROW);EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultat (ved hjælp af lodret output):

navn | StockItemTransactions2rows | 236667 reserveret | 9160 KBdata | 9088 KBindex_size | 8 KB

Så det faktiske resultat er meget tæt på det estimerede resultat.

I dette tilfælde sp_estimate_data_compression_savings gav et ret præcist skøn over slutresultatet.

Lad os køre sp_estimate_data_compression_savings en gang til, men ved at bruge en komprimeringstype NONE .

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

Resultat:

objektnavn | StockItemTransactions2schema_name | Warehouseindex_id | 0partitionsnummer | 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

Dette fortæller os, hvad der ville ske, hvis vi vendte tilbage til at bruge ingen komprimering.

I dette tilfælde viser den os nøjagtigt det samme tal (15.808 KB), som den viste os før anvendelsen af ​​komprimering, som, som du kan huske, var temmelig tæt på den faktiske størrelse (15.800 KB) returneret af sp_spaceused procedure.

Så lad os køre det igen og finde ud af det.

ALTER TABLE Warehouse.StockItemTransactions2REBUILD WITH (DATA_COMPRESSION =NONE);EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Resultat (ved hjælp af lodret output):

navn | StockItemTransactions2rows | 236667 reserveret | 15880 KBdata | 15800 KBindex_size | 8 KBubrugt | 72 KB

Så igen, sp_estimate_data_compression_savings var næsten spot on.

Dette er dog kun en simpel test. Andre test kunne returnere skøn, der er langt væk. Jeg har læst historier om sp_estimate_data_compression_savings returnerer vildt unøjagtige resultater, men det har jeg endnu ikke selv oplevet.

Derfor ser det ud til, at sp_estimate_data_compression_savings kan give et nøjagtigt estimat i samme tilfælde, og ikke så meget i andre.

Du skal beslutte, hvor meget afhængighed du vil lægge i denne lagrede procedure. Under alle omstændigheder bør du nok køre en test i dit udviklings- eller testmiljø, før du anvender komprimering i produktionen.


  1. Jeg vil bruge CASE-sætning til at opdatere nogle poster i sql server 2005

  2. Ufølsom søgning i Oracle

  3. Sådan sikrer du MySQL/MariaDB-servere

  4. 7645 Nul eller tomt fuldtekstprædikat