DBCC INDEXDEFRAG (Transact-SQL)

Berlaku untuk: SQL Server Azure SQL Managed Instance

Defragmentasi indeks tabel atau tampilan yang ditentukan.

Penting

Fitur ini akan dihapus dalam versi Microsoft SQL Server mendatang. Hindari menggunakan fitur ini dalam pekerjaan pengembangan baru, dan rencanakan untuk memodifikasi aplikasi yang saat ini menggunakan fitur ini. Gunakan ALTER INDEX sebagai gantinya.

Berlaku untuk: SQL Server 2008 (10.0.x) dan versi yang lebih baru

Konvensi sintaks transact-SQL

Sintaks

DBCC INDEXDEFRAG
(
    { database_name | database_id | 0 }
    , { table_name | table_id | view_name | view_id }
    [ , { index_name | index_id } [ , { partition_number | 0 } ] ]
)
    [ WITH NO_INFOMSGS ]

Catatan

Untuk melihat sintaks Transact-SQL untuk SQL Server 2014 dan yang lebih lama, lihat Dokumentasi versi sebelumnya.

Argumen

| database_name database_id | 0

Database yang berisi indeks untuk defragmentasi. Jika 0 ditentukan, database saat ini digunakan. Nama database harus mematuhi aturan untuk pengidentifikasi.

| table_name | table_id | view_name view_id

Tabel atau tampilan yang berisi indeks yang akan didefragmentasi. Nama tabel dan tampilan harus mematuhi aturan untuk pengidentifikasi.

| index_name index_id

Nama atau ID indeks yang akan didefragmentasi. Jika tidak ditentukan, pernyataan mendefinisikan semua indeks tabel atau tampilan yang ditentukan. Nama indeks harus mematuhi aturan untuk pengidentifikasi.

partition_number | 0

Nomor partisi indeks yang akan didefragmentasi. Jika tidak ditentukan atau jika 0 ditentukan, pernyataan mendefinisikan semua partisi dalam indeks yang ditentukan.

DENGAN NO_INFOMSGS

Menekan semua pesan informasi yang memiliki tingkat keparahan dari 0 hingga 10.

Keterangan

DBCC INDEXDEFRAG defragmentasi tingkat daun indeks sehingga urutan fisik halaman cocok dengan urutan logis kiri-ke-kanan dari node daun, oleh karena itu meningkatkan performa pemindaian indeks.

Catatan

Ketika DBCC INDEXDEFRAG dijalankan, defragmentasi indeks terjadi secara serial. Ini berarti bahwa operasi pada satu indeks dilakukan menggunakan satu utas. Tidak ada paralelisme yang terjadi. Selain itu, operasi pada beberapa indeks dari pernyataan yang sama DBCC INDEXDEFRAG dilakukan pada satu indeks pada satu waktu.

DBCC INDEXDEFRAG juga memampatkan halaman indeks, dengan mempertimbangkan faktor pengisian yang ditentukan ketika indeks dibuat. Halaman kosong apa pun yang dibuat karena pemadatan ini dihapus. Untuk informasi selengkapnya, lihat Menentukan Faktor Pengisian untuk Indeks.

Jika indeks mencakup lebih dari satu file, DBCC INDEXDEFRAG defragmentasi satu file pada satu waktu. Halaman tidak bermigrasi antar file.

DBCC INDEXDEFRAG melaporkan perkiraan persentase yang diselesaikan setiap lima menit. DBCC INDEXDEFRAG dapat dihentikan kapan saja dalam proses, dan pekerjaan yang telah selesai dipertahankan.

Tidak seperti DBCC DBREINDEX, atau operasi pembangunan indeks umumnya, DBCC INDEXDEFRAG adalah operasi online. Ini tidak menahan kunci jangka panjang. Oleh karena itu, DBCC INDEXDEFRAG tidak memblokir kueri atau pembaruan yang sedang berjalan. Karena waktu untuk defragmentasi terkait dengan tingkat fragmentasi, indeks yang relatif tidak difragmentasi dapat didefragmentasi lebih cepat daripada indeks baru dapat dibangun. Indeks yang sangat terfragmentasi mungkin membutuhkan waktu jauh lebih lama untuk didefragmentasi daripada membangun kembali.

Defragmentasi selalu dicatat sepenuhnya, terlepas dari pengaturan model pemulihan database. Untuk informasi selengkapnya, lihat MENGUBAH DATABASE (Transact-SQL). Defragmentasi indeks yang sangat terfragmentasi dapat menghasilkan lebih banyak log daripada pembuatan indeks yang dicatat sepenuhnya. Namun, defragmentasi dilakukan sebagai serangkaian transaksi pendek, sehingga log besar tidak perlu jika pencadangan log sering diambil atau jika pengaturan model pemulihan SEDERHANA.

Batasan

DBCC INDEXDEFRAG mengacak halaman daun indeks di tempat. Oleh karena itu, jika indeks diselingi dengan indeks lain pada disk, berjalan DBCC INDEXDEFRAG terhadap indeks tersebut tidak membuat semua halaman daun dalam indeks berdekatan. Untuk meningkatkan pengklusteran halaman, bangun ulang indeks.

DBCC INDEXDEFRAG tidak dapat digunakan untuk mendefinisikan indeks berikut:

  • Indeks yang dinonaktifkan.
  • Indeks dengan penguncian halaman diatur ke NONAKTIF.
  • Indeks spasial.

DBCC INDEXDEFRAG tidak didukung untuk digunakan pada tabel sistem.

Tataan hasil

DBCC INDEXDEFRAG mengembalikan tataan hasil berikut (nilai dapat bervariasi) jika indeks ditentukan dalam pernyataan (kecuali WITH NO_INFOMSGS ditentukan):

Pages Scanned Pages Moved Pages Removed
------------- ----------- -------------
359           346         8
  
(1 row(s) affected)
  
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Izin

Pemanggil harus memiliki tabel, atau menjadi anggota peran server tetap sysadmin , peran database tetap db_owner , atau peran database tetap db_ddladmin .

Contoh

A. Menggunakan DBCC INDEXDEFRAG untuk mendefragmentasi indeks

Contoh berikut mendefinisikan semua partisi PK_Product_ProductID indeks dalam Production.Product tabel dalam AdventureWorks2022 database.

DBCC INDEXDEFRAG (AdventureWorks2022, 'Production.Product', PK_Product_ProductID);
GO

B. Gunakan DBCC SHOWCONTIG dan DBCC INDEXDEFRAG untuk mendefragmentasi indeks dalam database

Contoh berikut menunjukkan cara sederhana untuk mendefragmentasi semua indeks dalam database yang terfragmentasi di atas ambang batas yang dinyatakan.

/*Perform a 'USE <database name>' to select the database in which to run the script.*/
-- Declare variables
SET NOCOUNT ON;
DECLARE @tablename VARCHAR(255);
DECLARE @execstr   VARCHAR(400);
DECLARE @objectid  INT;
DECLARE @indexid   INT;
DECLARE @frag      DECIMAL;
DECLARE @maxfrag   DECIMAL;
  
-- Decide on the maximum fragmentation to allow for.
SELECT @maxfrag = 30.0;
  
-- Declare a cursor.
DECLARE tables CURSOR FOR
   SELECT TABLE_SCHEMA + '.' + TABLE_NAME
   FROM INFORMATION_SCHEMA.TABLES
   WHERE TABLE_TYPE = 'BASE TABLE';
  
-- Create the table.
CREATE TABLE #fraglist (
   ObjectName CHAR(255),
   ObjectId INT,
   IndexName CHAR(255),
   IndexId INT,
   Lvl INT,
   CountPages INT,
   CountRows INT,
   MinRecSize INT,
   MaxRecSize INT,
   AvgRecSize INT,
   ForRecCount INT,
   Extents INT,
   ExtentSwitches INT,
   AvgFreeBytes INT,
   AvgPageDensity INT,
   ScanDensity DECIMAL,
   BestCount INT,
   ActualCount INT,
   LogicalFrag DECIMAL,
   ExtentFrag DECIMAL);
  
-- Open the cursor.
OPEN tables;
  
-- Loop through all the tables in the database.
FETCH NEXT
   FROM tables
   INTO @tablename;
  
WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
   INSERT INTO #fraglist
   EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
      WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
   FETCH NEXT
      FROM tables
      INTO @tablename;
END;
  
-- Close and deallocate the cursor.
CLOSE tables;
DEALLOCATE tables;
  
-- Declare the cursor for the list of indexes to be defragged.
DECLARE indexes CURSOR FOR
   SELECT ObjectName, ObjectId, IndexId, LogicalFrag
   FROM #fraglist
   WHERE LogicalFrag >= @maxfrag
      AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0;
  
-- Open the cursor.
OPEN indexes;
  
-- Loop through the indexes.
FETCH NEXT
   FROM indexes
   INTO @tablename, @objectid, @indexid, @frag;
  
WHILE @@FETCH_STATUS = 0
BEGIN
   PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ',
      ' + RTRIM(@indexid) + ') - fragmentation currently '
       + RTRIM(CONVERT(varchar(15),@frag)) + '%';
   SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ',
       ' + RTRIM(@indexid) + ')';
   EXEC (@execstr);
  
   FETCH NEXT
      FROM indexes
      INTO @tablename, @objectid, @indexid, @frag;
END;
  
-- Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;
  
-- Delete the temporary table.
DROP TABLE #fraglist;
GO

Lihat juga