Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Oszacuj oszczędności związane z kompresją danych w SQL Server

SQL Server ma systemową procedurę składowaną o nazwie sp_estimate_data_compression_savings , który pozwala sprawdzić rozmiar obiektu i jego szacowany rozmiar przy różnych poziomach kompresji.

Jeśli obiekt jest już skompresowany, możesz użyć tej procedury, aby oszacować jego rozmiar po ponownej kompresji.

Obiekty można skompresować za pomocą kompresji wierszy, stron, magazynu kolumn lub archiwum magazynu kolumn.

Kompresja może być oceniana dla całych tabel lub ich części. Obejmuje to sterty, indeksy klastrowe, indeksy nieklastrowane, indeksy magazynu kolumn, widoki indeksowane oraz partycje tabel i indeksów.

Przykład

Oto przykład do zademonstrowania.

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

Wynik:

+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                   |
+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Aby oszczędzić Ci konieczności zbyt częstego przewijania w bok, tutaj ponownie używamy pionowego wyjścia:

-[ 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

Rozmiary kompresji podane są w kilobajtach (KB).

W tym przypadku wydaje się, że stosowanie kompresji wierszy w tej tabeli przynosi znaczną korzyść. Przechodzi od 32 KB do 8 KB. Zakłada się, że jest to dokładne oszacowanie.

Kiedy uruchomiłem poprzedni kod, podałem wszystkie nazwy argumentów. Możesz również pominąć te nazwy i po prostu podać wartości.

Tak:

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

Tak czy inaczej, wynik jest taki sam.

Tutaj jest znowu, ale tym razem określam PAGE zamiast ROW jako typ kompresji.

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

Wynik (przy użyciu wyjścia pionowego):

-[ 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

W tym przypadku liczby wyglądają tak samo, ale w zależności od danych możesz uzyskać bardzo różne liczby.

Typy kompresji

@data_compression argument przyjmuje następujące wartości:

  • BRAK
  • ROW
  • STRONA
  • SKLEP KOLUMN
  • COLUMNSTORE_ARCHIVE

Oto opcje kompresji dostępne podczas tworzenia/zmiany tabeli lub indeksu.

SKLEP KOLUMN i COLUMNSTORE_ARCHIVE opcje są dostępne tylko w przypadku indeksów magazynu kolumn (w tym zarówno nieklastrowanych, jak i klastrowanych indeksów magazynu kolumn).

@index_id Argument

Czasami wyniki mogą zwracać wiele wierszy dla danego obiektu, każdy z innym index_id .

Jeśli wolisz, możesz zawęzić go do określonego indeksu. Aby to zrobić, podaj index_id do @index_id argument.

Na przykład, kiedy uruchamiam poniższy kod, zwracanych jest osiem wierszy, każdy z innym index_id wartości.

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

Wynik:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Gdybyśmy chcieli zawęzić go do jednego wiersza, moglibyśmy użyć jego index_id .

Tak:

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

Wynik:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Możesz także użyć @numer_partycji zrobić to samo z partycjami.

Ilość kompresji może się znacznie różnić

Stopień kompresji, jaki uzyskasz, będzie zależeć od danych i rodzaju kompresji.

ROW kompresja, na przykład, usuwa niepotrzebne bajty z wartości kolumn, przechowując je w formacie o zmiennej długości. PAGE z drugiej strony kompresja przechowuje powtarzające się wartości tylko raz na stronę i ustawia wskaźnik z odpowiednich kolumn na stronie.

Czasami może się okazać, że kompresja obiektu nie zawsze zmniejsza jego rozmiar, a w niektórych przypadkach może nawet zwiększyć jego rozmiar.

Może się tak zdarzyć, jeśli Twoje kolumny używają typu danych, który nie korzysta z kompresji.

Ponadto kompresja wierszy zmniejsza obciążenie metadanych, ale w niektórych przypadkach obciążenie może być większe niż w przypadku starego formatu przechowywania.

Jeśli Twoje dane nie uzyskują żadnych korzyści z kompresji ze względu na ich typ danych, prawdopodobne jest, że obciążenie spowoduje wzrost wymagań dotyczących pamięci, a nie ich spadek.

Jednak różnice w rozmiarze kompresji będą również zależeć od rzeczywistych danych. Na przykład, jeśli masz znak(10) kolumna, kompresja usunie wszystkie końcowe znaki dopełnienia. Jeśli masz wiele wierszy ze znakami dopełnienia końcowego, powinieneś uzyskać lepszy wynik niż w przypadku braku (lub kilku) wierszy ze znakami dopełnienia końcowego.

Jak szacuje kompresję?

Po wykonaniu sp_estimate_data_compression_savings , pobiera próbkę danych, a następnie ładuje je do równoważnej tabeli i indeksu utworzonego w tempdb . Utworzenie tabeli lub indeksu w tempdb jest następnie kompresowany do żądanego ustawienia i obliczane są szacunkowe oszczędności kompresji.

Jak to jest dokładne?

Możesz uzyskać mieszane wyniki podczas korzystania z sp_estimate_data_compression_savings .

Przeprowadźmy mały test.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Wynik (przy użyciu wyjścia pionowego):

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

sp_spaceused procedura składowana pokazuje nam faktycznie wykorzystane miejsce na dysku. W tym przypadku dane zajmują 15 800 KB miejsca na dysku.

Teraz wykonam sp_estimate_data_compression_savings aby zobaczyć, jaką oszczędność miejsca uzyskam, jeśli zastosuję kompresję do tej tabeli.

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

Wynik (przy użyciu wyjścia pionowego):

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

Zgodnie z tymi wynikami zastosowanie kompresji wierszy do tej tabeli zmniejszy jej rozmiar z 15 808 KB do szacowanego rozmiaru zaledwie 9096 KB. Nie tak źle.

Zastosujmy teraz kompresję wierszy do tej tabeli, a następnie uruchommy sp_spaceused ponownie.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Wynik (przy użyciu wyjścia pionowego):

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

Tak więc rzeczywisty wynik jest bardzo zbliżony do wyniku szacunkowego.

W takim przypadku sp_estimate_data_compression_savings dostarczyło dość dokładne oszacowanie wyniku końcowego.

Uruchommy sp_estimate_data_compression_savings jeszcze raz, ale przy użyciu typu kompresji BRAK .

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

Wynik:

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 mówi nam, co by się stało, gdybyśmy wrócili do braku kompresji.

W tym przypadku pokazuje nam dokładnie tę samą liczbę (15 808 KB), którą pokazał nam przed zastosowaniem kompresji, która, jak pamiętasz, była dość zbliżona do rzeczywistego rozmiaru (15 800 KB) zwróconego przez sp_spaceused procedura.

Więc uruchommy go jeszcze raz i przekonajmy się.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Wynik (przy użyciu wyjścia pionowego):

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

Więc znowu, sp_estimate_data_compression_savings był prawie na miejscu.

To jednak tylko jeden prosty test. Inne testy mogą zwrócić szacunki, które są odległe. Czytałem historie o sp_estimate_data_compression_savings zwracam szalenie niedokładne wyniki, ale sam jeszcze tego nie doświadczyłem.

Dlatego wydaje się, że sp_estimate_data_compression_savings może zapewnić dokładne oszacowanie w tych samych przypadkach, a nie w innych.

Musisz zdecydować, na ile polegasz na tej procedurze składowanej. W każdym razie prawdopodobnie powinieneś uruchomić test w swoim środowisku programistycznym lub testowym przed zastosowaniem kompresji w środowisku produkcyjnym.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Radzenie sobie z wartościami NULL w SQL Server

  2. Wyeliminuj i zmniejsz nakładające się zakresy dat

  3. SQL Server BULK INSERT z systemu Linux

  4. Tabela przestawna serwera SQL Server z agregacjami wielu kolumn

  5. SQL DEFAULT Ograniczenie do wstawiania kolumny z wartością domyślną do tabeli SQL Server