Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Perkirakan Penghematan Kompresi Data di SQL Server

SQL Server memiliki prosedur tersimpan sistem yang disebut sp_estimate_data_compression_savings , yang memungkinkan Anda memeriksa ukuran objek dan perkiraan ukurannya dengan berbagai tingkat kompresi.

Jika objek sudah dikompresi, Anda dapat menggunakan prosedur ini untuk memperkirakan ukurannya saat dikompres ulang.

Objek dapat dikompresi dengan menggunakan kompresi arsip baris, halaman, penyimpanan kolom, atau penyimpanan kolom.

Kompresi dapat dievaluasi untuk seluruh tabel atau bagian dari tabel. Ini termasuk heaps, indeks berkerumun, indeks nonclustered, indeks columnstore, tampilan terindeks, dan tabel dan partisi indeks.

Contoh

Berikut ini contoh untuk didemonstrasikan.

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

Hasil:

+-------------------+---------------+---------- ---+-------------------+-------------------------- -------------------+----------------------------- ------------------+-------------------------------- --------------------+---------------------------- -------------------------+| nama_objek | nama_skema | indeks_id | nomor_partisi | 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 | Gudang | 1 | 1 | 32 | 8 | 40 | 16 |+-------------------+---------------+----------- -+--------------------+---------------------------- ------------------+------------------------------- ----------------+--------------------------------- -------------------+----------------------------- ------------------------+

Untuk menyelamatkan Anda dari keharusan melakukan terlalu banyak scroll ke samping, ini dia lagi menggunakan output vertikal:

-[ REKAM 1 ]-------------------------nama_objek | StockItemHoldingsschema_name | Warehouseindex_id | 1partition_number | 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

Ukuran kompresi dalam kilobyte (KB).

Dalam hal ini, tampaknya ada manfaat yang signifikan dalam menggunakan kompresi baris pada tabel ini. Dari 32 KB menjadi 8 KB. Ini mengasumsikan bahwa ini adalah perkiraan yang akurat.

Ketika saya menjalankan kode sebelumnya, saya memberikan semua nama argumen. Anda juga dapat menghilangkan nama-nama ini, dan hanya memberikan nilainya.

Seperti ini:

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

Bagaimanapun, hasilnya tetap sama.

Ini dia lagi, tapi kali ini saya tentukan PAGE bukannya ROW sebagai jenis kompresi.

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

Hasil (menggunakan keluaran vertikal):

-[ REKAM 1 ]-------------------------nama_objek | StockItemHoldingsschema_name | Warehouseindex_id | 1partition_number | 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

Dalam hal ini, angkanya terlihat sama, tetapi Anda bisa mendapatkan angka yang sangat berbeda, tergantung pada data Anda.

Jenis Kompresi

@data_compression argumen menerima nilai berikut:

  • NONE
  • ROW
  • PAGE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Ini adalah opsi kompresi yang tersedia saat membuat/mengubah tabel atau indeks.

COLUMNSTORE dan COLUMNSTORE_ARCHIVE opsi hanya tersedia pada indeks columnstore (termasuk indeks columnstore nonclustered dan indeks columnstore berkerumun).

@index_id Argumen

Terkadang hasil Anda mungkin menampilkan beberapa baris untuk objek tertentu, masing-masing dengan index_id . yang berbeda .

Anda dapat mempersempitnya ke indeks tertentu jika Anda mau. Untuk melakukannya, berikan index_id ke @index_id argumen.

Misalnya, ketika saya menjalankan kode berikut, delapan baris dikembalikan, masing-masing dengan index_id yang berbeda nilai.

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

Hasil:

+-------------+---------------+------ ------+--------------------+---------------------- -----------------------+-------------------------- ----------+---------------------------- ------------------------+---------------------------- -----------------------------+| nama_objek | nama_skema | indeks_id | nomor_partisi | 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) ||-----------------------+---------------+---- --------+--------------------+-------------------- -------------------------+------------------------ -----------------------+-------------------------- -----------------------+----------------------- -------------------------------||| Transaksi StockItem | Gudang | 2 | 1 | 5568 | 4120 | 4280 | 3168 || Transaksi StockItem | Gudang | 3 | 1 | 5184 | 3720 | 4264 | 3064 || Transaksi StockItem | Gudang | 4 | 1 | 5568 | 4224 | 4288 | 3256 || Transaksi StockItem | Gudang | 5 | 1 | 5528 | 4416 | 4280 | 3424 || Transaksi StockItem | Gudang | 6 | 1 | 5192 | 3456 | 4264 | 2840 || Transaksi StockItem | Gudang | 7 | 1 | 5192 | 3464 | 4264 | 2848 || Transaksi StockItem | Gudang | 9 | 1 | 5416 | 4456 | 4264 | 3512 || Transaksi StockItem | Gudang | 1 | 1 | 2720 ​​| 9096 | 2720 ​​| 9096 |+-------------+---------------+------- -----+--------------------+----------------------- -----------------------+--------------------------- --------------------+---------------------------- -----------------------+-------------------------- ----------------------------+

Jika kita ingin mempersempitnya menjadi hanya satu baris, kita bisa menggunakan index_id .

Seperti ini:

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

Hasil:

+-------------+---------------+------ ------+--------------------+---------------------- -----------------------+-------------------------- ------------+---------------------------- ------------------------+---------------------------- -----------------------------+| nama_objek | nama_skema | indeks_id | nomor_partisi | 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) ||-----------------------+---------------+---- --------+--------------------+-------------------- -------------------------+------------------------ -----------------------+-------------------------- -----------------------+----------------------- -------------------------------||| Transaksi StockItem | Gudang | 1 | 1 | 2720 ​​| 9096 | 2720 ​​| 9096 |+-------------+---------------+------- -----+--------------------+----------------------- -----------------------+--------------------------- --------------------+---------------------------- -----------------------+-------------------------- ----------------------------+

Anda juga dapat menggunakan @partition_number untuk melakukan hal yang sama dengan partisi.

Jumlah Kompresi Dapat Bervariasi Secara Signifikan

Jumlah kompresi yang Anda dapatkan akan bergantung pada data dan jenis kompresi.

ROW kompresi, misalnya, menghapus byte yang tidak dibutuhkan dari nilai kolom dengan menyimpannya dalam format panjang variabel. PAGE kompresi, di sisi lain, menyimpan nilai berulang hanya sekali per halaman, dan menetapkan penunjuk dari masing-masing kolom di dalam halaman.

Terkadang Anda mungkin menemukan bahwa mengompresi suatu objek tidak selalu mengurangi ukurannya, dan dalam beberapa kasus sebenarnya dapat meningkatkan ukurannya.

Ini bisa terjadi jika kolom Anda menggunakan tipe data yang tidak memanfaatkan kompresi.

Juga, kompresi baris mengurangi overhead metadata, tetapi dalam beberapa kasus, overhead mungkin lebih besar daripada format penyimpanan lama.

Jika data Anda tidak menerima manfaat dari kompresi karena jenis datanya, kemungkinan overhead tersebut akan menyebabkan peningkatan kebutuhan penyimpanan, bukan penurunan.

Tetapi variasi ukuran kompresi juga akan tergantung pada data aktual. Misalnya, jika Anda memiliki char(10) kolom, kompresi akan menghapus semua karakter padding yang tertinggal. Jika Anda memiliki banyak baris dengan karakter bantalan tambahan, Anda akan mendapatkan hasil yang lebih baik daripada jika Anda tidak memiliki (atau sedikit) baris dengan karakter bantalan tambahan.

Bagaimana Cara Memperkirakan Kompresi?

Saat Anda menjalankan sp_estimate_data_compression_savings , dibutuhkan sampel data, lalu memuatnya ke dalam tabel dan indeks yang setara yang dibuat di tempdb . Tabel atau indeks dibuat di tempdb kemudian dikompresi ke pengaturan yang diminta dan perkiraan penghematan kompresi dihitung.

Seberapa Akurat?

Anda mungkin mendapatkan hasil yang beragam saat menggunakan sp_estimate_data_compression_savings .

Mari kita jalankan tes kecil.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Hasil (menggunakan keluaran vertikal):

nama | StockItemTransactions2rows | 236667 dipesan | 15944 KBdata | 15800 KBindex_size | 8 KBBelum digunakan | 136 KB

sp_spaceused prosedur tersimpan menunjukkan kepada kita ruang disk yang sebenarnya digunakan. Dalam hal ini, data menggunakan 15.800 KB ruang disk.

Sekarang, saya akan menjalankan sp_estimate_data_compression_savings untuk melihat penghematan ruang apa yang akan saya dapatkan jika saya menerapkan kompresi ke tabel itu.

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

Hasil (menggunakan keluaran vertikal):

nama_objek | StockItemTransactions2schema_name | Warehouseindex_id | 0partition_number | 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

Menurut hasil ini, menerapkan kompresi baris ke tabel ini akan mengurangi ukurannya dari 15.808 KB menjadi perkiraan ukuran hanya 9.096 KB. Tidak terlalu buruk.

Sekarang mari kita terapkan kompresi baris ke tabel ini, lalu jalankan sp_spaceused lagi.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Hasil (menggunakan keluaran vertikal):

nama | StockItemTransactions2rows | 236667 dipesan | 9160 KBdata | 9088 KBindex_size | 8 KB

Jadi hasil sebenarnya sangat mendekati hasil estimasi.

Dalam hal ini, sp_estimate_data_compression_savings memberikan perkiraan hasil akhir yang cukup akurat.

Mari kita jalankan sp_estimate_data_compression_savings sekali lagi, tetapi menggunakan jenis kompresi NONE .

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

Hasil:

nama_objek | StockItemTransactions2schema_name | Warehouseindex_id | 0partition_number | 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

Ini memberi tahu kita apa yang akan terjadi jika kita kembali menggunakan tanpa kompresi.

Dalam hal ini menunjukkan kepada kita angka yang sama persis (15.808 KB) yang ditunjukkannya kepada kita sebelum menerapkan kompresi yang, seperti yang Anda ingat, cukup dekat dengan ukuran sebenarnya (15.800 KB) yang dikembalikan oleh sp_spaceused prosedur.

Jadi mari kita jalankan lagi dan cari tahu.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2'; 

Hasil (menggunakan keluaran vertikal):

nama | StockItemTransactions2rows | 236667 dipesan | 15880 KBdata | 15800 KBindex_size | 8 KBBelum digunakan | 72 KB

Jadi sekali lagi, sp_estimate_data_compression_savings hampir tepat.

Namun, ini hanya satu tes sederhana. Tes lain dapat mengembalikan perkiraan yang jauh. Saya sudah membaca cerita sp_estimate_data_compression_savings mengembalikan hasil yang sangat tidak akurat, tetapi saya sendiri belum mengalaminya.

Oleh karena itu, tampaknya sp_estimate_data_compression_savings dapat memberikan perkiraan yang akurat dalam kasus yang sama, dan tidak begitu banyak dalam kasus lain.

Anda harus memutuskan seberapa besar ketergantungan yang ingin Anda masukkan ke dalam prosedur tersimpan ini. Bagaimanapun, Anda mungkin harus menjalankan pengujian di lingkungan pengembangan atau pengujian Anda sebelum menerapkan kompresi dalam produksi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server:Kolom ke Baris

  2. Fungsi format tanggal SQL Server

  3. Urutan sebagai nilai default untuk kolom

  4. Apa yang terjadi jika Anda tidak melakukan transaksi ke database (misalnya, SQL Server)?

  5. Penyimpanan data terbaik untuk miliaran baris