September 14, 2008

Index Defrag di SQL Server

beberapa waktu yang lalu, nemuin kasus ukuran database yang membengkak. coba di shrink, emang berkurang, tapi yg berkurang banyak dari log file nya aja. untuk datanya pengurangan nya tidak signifikan. akhirnya diskusi deh ama atok_sub. ternyata mas atok udah nemuin cara yg bisa mengurangi ukuran datanya, yaitu dengan index defrag.
database yang sering diakses, index nya sering berubah dan ukuran nya membesar. klo di sql server, index menjadi 1 dengan file mdf nya. dengan ukuran index yang besar dan susunan yg tidak teratur, ternyata juga membebani proses CRUD di database. maka dari itu, index juga harus di maintain, agar bisa kembali ke performa yang bagus.
test yang coba saya lakukan adalah dengan menjalankan script index defrag pada database dengan ukuran sekitar 145 MB. db itu log file nya sudah di shrink sehingga tinggal 1 MB aja. waktu yang dibutuhkan untuk menjalankan script sekitar 2 menit. tapi itu tergantung dari ukuran database dan hardware mesin kita. sebab utk database yang ukurannya besar, butuh waktu lebih lama dan klo hardwarenya kurang mencukupi, bisa timeout..hehehehe. test yang saya lakukan menggunakan hardware centrino core 2 duo 2.2 Ghz, memory 2.5 Gb.
setelah selesai menjalankan script, ukuran file db tidak langsung berkurang. perlu 1 ritual lagi agar ukuran file nya berkurang, yaitu shrink database. setelah di shrink, ukuran database berkurang cukup signifikan. dari 145 MB menjadi 93.5 MB. 50 MB lebih berkurang nya.
selain ukuran database yang berkurang, efek lain adalah reporting dari client yang biasanya timeout, dengan index defrag bisa langsung lancar jaya..hehehe.
script nya seperti di bawah ini, gak terlalu panjang kok.

DECLARE @TableName sysname
DECLARE @indid int
DECLARE cur_tblfetch CURSOR FOR
SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'
OPEN cur_tblfetch
FETCH NEXT FROM cur_tblfetch INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE cur_indfetch CURSOR FOR
    SELECT indid FROM sysindexes WHERE id = OBJECT_ID (@TableName) and keycnt > 0
    OPEN cur_indfetch
    FETCH NEXT FROM cur_indfetch INTO @indid
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT 'Derfagmenting index_id = ' + convert(char(3), @indid) + 'of the ' + rtrim(@TableName) + ' table'
        IF @indid <> 255 DBCC INDEXDEFRAG (0, @TableName, @indid)
        FETCH NEXT FROM cur_indfetch INTO @indid
    END
    CLOSE cur_indfetch
    DEALLOCATE cur_indfetch
    FETCH NEXT FROM cur_tblfetch INTO @TableName
END
CLOSE cur_tblfetch
DEALLOCATE cur_tblfetch

No comments: