Apakah indeks terkompresi SQL Server tetap dikompresi pada pembangunan kembali tanpa menentukan kompresi data?

13

Setelah satu membangun kembali indeks SQL Server mereka menggunakan kompresi halaman ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), apakah membangun kembali berikutnya (seperti yang dilakukan oleh beberapa skrip pemeliharaan melewati ambang fragmentasi tertentu) perlu menentukan kompresi data lagi? Apakah indeks akan didekompresi secara efektif?

Paul-Sebastian Manole
sumber

Jawaban:

22

Indeks tetap terkompresi ketika membangun kembali / mengatur ulang mereka.

Buat tabel dan indeks terkompresi

 CREATE TABLE DBO.TEST_INDX(id int, bla varchar(255));
 CREATE INDEX IX1 ON dbo.TEST_INDX(id)  WITH (DATA_COMPRESSION = PAGE);

Periksa Kompresi

 SELECT i.name, p.data_compression_desc 
 FROM sys.partitions P
 INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
 WHERE P.data_compression > 0 and I.name = 'IX1';

Hasil

name    data_compression_desc
IX1     PAGE

Buat ulang indeks

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Periksa Kompresi

 SELECT i.name, p.data_compression_desc 
 FROM sys.partitions P
 INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
 WHERE P.data_compression > 0 and I.name = 'IX1'

Hasil

name    data_compression_desc
IX1     PAGE

Menonaktifkan mereka dan kemudian membangun kembali memiliki hasil yang berbeda, karena penonaktifan menghapus indeks, sambil tetap mempertahankan definisi indeks.

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD ;

Hasil

name    data_compression_desc

Kompresi hilang, definisi kompresi juga akan hilang ketika menjatuhkan dan membuat indeks melalui SSMS tanpa mengadaptasi skrip pembuatan Indeks.

Mengapa?

Karena opsi data_compression tidak dipertahankan ketika membuat skrip dari Index buat pernyataan.

namun, jika kami menonaktifkan indeks, membangun kembali dengan kompresi dan kemudian membangun kembali lagi:

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD  WITH (DATA_COMPRESSION = PAGE);
alter index IX1 on  DBO.TEST_INDX REBUILD;

Hasil

name    data_compression_desc
IX1 PAGE

Menguji pembangunan kembali dengan solusi pemeliharaan Ola hallengren

Parameter tersebut dimodifikasi untuk tujuan pengujian.

Tambahkan beberapa data untuk sampai ke satu halaman, karena diperlukan untuk parameter MinNumberOfPages.

INSERT INTO dbo.TEST_INDX(id,bla)
VALUES(5,'test');
go 10 

Jalankan indeks optim mengoptimalkan untuk mencetak pernyataan.

EXECUTE dbo.IndexOptimize
@Databases = 'TestDB',
@FragmentationLow = 'INDEX_REBUILD_ONLINE',
@FragmentationMedium = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@Indexes = 'TestDB.DBO.TEST_INDX',
@Execute = 'N',
@MinNumberOfPages = 1;

Hasil:

Command: ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

Comment: ObjectType: Table, IndexType: NonClustered, ImageTex
t: No, NewLOB: No, FileStream: No, ColumnStore: No, AllowPageLocks: Yes, PageCount: 1, Fragmentation: 0
Outcome: Not Executed
Duration: 00:00:00
Date and time: 2019-01-09 14:48:12

Menjalankan perintah yang dihasilkan

ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

Kompresi tetap dipertahankan

name    data_compression_desc
IX1 PAGE

Menguji pembangunan kembali dengan rencana pemeliharaan (saya akan sangat mendukung solusi ola)

Buat kembali indeks

masukkan deskripsi gambar di sini

Pilih tabel tes

masukkan deskripsi gambar di sini

Tambahkan beberapa level fragmentasi tes.

masukkan deskripsi gambar di sini

Masukkan beberapa nilai untuk menjalankan fragmentasi

INSERT INTO dbo.TEST_INDX(id)
SELECT id from TEST_INDX
go 4

Periksa persentase fragmentasi

SELECT 
I.[name] AS  INDX ,
IPS.avg_fragmentation_in_percent,
IPS.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), object_id('[dbo].[TEST_INDX]'), NULL, NULL, NULL) AS IPS
INNER JOIN sys.indexes AS I ON I.[object_id] = IPS.[object_id]
AND IPS.index_id = I.index_id
WHERE IPS.database_id = DB_ID()
and I.name = 'IX1'

Hasil

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

Jalankan rencananya

masukkan deskripsi gambar di sini

Bagian yang menarik di sini, ketika melihat laporan rencana, adalah bahwa DATA_COMPRESSION = PAGEopsi ditambahkan ke REBUILDperintah yang dihasilkan !

Command:USE [TestDB]
GO
ALTER INDEX [IX1] ON [dbo].[TEST_INDX] REBUILD PARTITION = ALL WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, RESUMABLE = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80, DATA_COMPRESSION = PAGE)

Fragmentasi:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Kompresi:

name    data_compression_desc
IX1 PAGE
Randi Vertongen
sumber
Saya menemukan posting Anda ketika saya menemukan bahwa 3 database yang saya telah kompres semua kehilangan kompresi mereka & saya harus menerapkannya kembali. Sebagai bagian dari pekerjaan itu, saya menguji & mengonfirmasi hasil Anda tetapi tidak tahu bagaimana ini terjadi. Satu-satunya kemungkinan lain yang saya temui adalah, jika indeks dinonaktifkan, mereka kehilangan kompresi saat dibangun kembali. Tampaknya tidak demikian, per tim ETL kami. Saya juga mengajukan pertanyaan ini di SQLServerCentral: sqlservercentral.com/Forums/2017336/Databases-Lost-Compression Benar-benar bingung bagaimana ini terjadi.
Marvel
Hai @ Marvel, bisa jadi beberapa proses lain indeks diciptakan kembali pada database? Misalnya beberapa aplikasi melakukan 'upgrade' di mana mereka drop dan membuat indeks yang tak terhitung jumlahnya. Namun saya tidak berpikir bahwa siapa pun akan dapat memberikan penjelasan yang jelas tanpa rincian lebih lanjut. Lain kali hal itu terjadi, Anda dapat menemukan tanggal pembuatan indeks, dan menemukan jika mereka dibuat kembali (misalnya dengan kueri di tautan ini: stackoverflow.com/questions/7579932/… . Kalau tidak, Anda selalu dapat bertanya sebagai pertanyaan, tapi saya tahu berpikir bahwa Anda perlu memberikan lebih banyak informasi
Randi Vertongen
1
Terima kasih, Randi! Saya mengatur audit SCHEMA_OBJECT_CHANGE_GROUP pada database tetapi ini pasti akan membantu saya untuk mengurai log lebih cepat. Saya telah menemukan salah satu penyebab - pemilik basis data, orang yang meminta kompresi telah memodifikasi tabel & indeks secara konstan. Dia tidak menyadari bahwa ketika dia membuat tabel baru & memindahkan data lama di & membuat indeks baru akan menyebabkan kompresi menjadi hilang. :( Saya telah memberinya cara yang benar untuk membuat tabel & indeksnya. Namun, saya pikir dia bukan satu-satunya penyebab. Saya tidak bisa membayangkan dia melakukan ini pada e
Marvel