SQL Database fragmentasi file fisik

19

Saya tahu bahwa sebenarnya ada tiga jenis fragmentasi yang perlu saya perhatikan sebagai DBA:

  1. Indeks Fragmentasi dalam file data SQL, termasuk fragmentasi indeks tabel (tabel). Identifikasi ini menggunakan DBCC SHOWCONTIG (dalam SQL 2000) atau sys.dm_ db_ index_ physical_ stats (in 2005+).

  2. VLF Fragmentasi di dalam file SQL Log. Jalankan DBCC LOGINFO untuk melihat berapa banyak VLF di setiap file log SQL Anda.

  3. Fragmentasi file fisik dari file database pada hard drive. Diagnosis ini dengan menggunakan utilitas "Disk Defragmenter" di Windows. (terinspirasi oleh posting blog yang luar biasa ini )

Banyak perhatian diberikan pada indeks fragmentasi (lihat jawaban Serverfault yang sangat baik dari Paul Randall), jadi itu bukan fokus pertanyaan saya.

Saya tahu saya bisa mencegah fragmentasi fisik (dan fragmentasi VLF) ketika database awalnya dibuat dengan merencanakan file data yang diharapkan dan ukuran log, karena fragmentasi ini paling sering terjadi dari sering tumbuh dan menyusut, tapi saya punya beberapa pertanyaan tentang cara memperbaiki fragmentasi fisik setelah diidentifikasi:

  • Pertama-tama, apakah fragmentasi fisik bahkan relevan pada Enterprise SAN? Dapatkah saya / saya harus menggunakan Windows Defragmenter pada drive SAN, atau haruskah tim SAN menggunakan utilitas defragmenting internal? Apakah analisis fragmentasi yang saya dapatkan dari alat Windows bahkan akurat ketika dijalankan pada drive SAN?

  • Seberapa besar masalah fragmentasi fisik pada kinerja SQL? (Mari kita asumsikan array drive internal, sambil menunggu hasil dari pertanyaan sebelumnya.) Apakah ini kesepakatan yang LEBIH BESAR daripada fragmentasi indeks internal? Atau apakah itu benar-benar jenis masalah yang sama (drive harus melakukan pembacaan acak, bukan pembacaan berurutan)

  • Apakah defragmenting (atau pembangunan kembali) indeks membuang-buang waktu jika drive secara fisik terfragmentasi? Apakah saya perlu memperbaiki yang satu sebelum saya membahas yang lain?

  • Apa cara terbaik untuk memperbaiki fragmentasi file fisik pada kotak SQL produksi? Saya tahu saya bisa mematikan layanan SQL dan menjalankan Windows Defrag, tetapi saya juga mendengar tentang teknik di mana Anda melakukan pencadangan penuh, jatuhkan database, lalu kembalikan dari cadangan ke pengandar kosong. Apakah teknik yang terakhir ini direkomendasikan? Apakah memulihkan dari cadangan seperti ini juga membuat indeks dari awal, menghilangkan fragmentasi indeks internal? Atau apakah itu hanya mengembalikan urutan halaman ke sama seperti ketika cadangan diambil? (Kami menggunakan cadangan Quest Lightspeed dengan kompresi, jika itu penting.)

PEMBARUAN : Sejauh ini jawaban yang baik tentang apakah akan men-defrag drive SAN (TIDAK) dan apakah defragmentasi indeks masih bermanfaat pada drive yang terfragmentasi secara fisik (YA).

Adakah orang lain yang mau mempertimbangkan metode terbaik untuk benar-benar melakukan defragmentasi? Atau perkiraan lama waktu yang Anda harapkan untuk mendefrag drive besar yang terfragmentasi, katakanlah sekitar 500GB? Relevan, jelas, karena saat itulah server SQL saya akan turun!

Juga, jika ada yang punya info anekdotal tentang peningkatan kinerja SQL yang telah Anda buat dengan memperbaiki fragmentasi fisik, itu akan sangat bagus juga. Posting blog Mike berbicara tentang mengungkap masalah, tetapi tidak spesifik tentang perbaikan apa yang dibuatnya.

BradC
sumber

Jawaban:

9

Saya pikir artikel ini memberikan gambaran yang sangat baik tentang defragmentasi drive SAN

http://www.las-solanas.com/storage_virtualization/san_volume_defragmentation.php

Poin mendasarnya adalah defragmenting tidak direkomendasikan pada penyimpanan SAN karena sulit untuk mengkorelasikan lokasi fisik blok pada disk ketika lokasi telah divirtualisasi oleh SAN saat menyajikan LUN.

Jika Anda menggunakan pemetaan perangkat RAW atau Anda memiliki akses langsung ke set RAID yang merupakan LUN yang bekerja dengan Anda, saya bisa melihat degfragmentasi memiliki efek positif, tetapi jika Anda diberikan LUN "virtual" dari RAID yang dibagi 5 set, tidak.

Kevin Kuphal
sumber
Artikel yang luar biasa. Tepat tentang drive SAN.
BradC
7

Beberapa bagian untuk pertanyaan dan jawaban ini:

Fragmentasi file fisik tidak benar-benar relevan untuk penyimpanan Enterprise SAN, seperti yang telah ditunjukkan Kevin - jadi tidak ada yang ditambahkan di sana. Itu benar-benar turun ke subsistem I / O dan seberapa besar kemungkinan Anda dapat membuat drive beralih dari I / O yang lebih acak ketika melakukan pemindaian ke I / O yang lebih berurutan saat melakukan pemindaian. untuk DAS, kemungkinan besar Anda akan melakukannya, untuk SAN irisan-n-dadu yang kompleks, mungkin tidak.

Defragging tingkat sistem file - hanya melakukannya dengan SQL shut down. Saya sendiri tidak pernah mengalami masalah di sini (karena saya belum pernah melakukan defrag file database SQL online yang terbuka), tetapi saya telah mendengar banyak bukti anekdotal dari pelanggan dan klien tentang masalah korupsi aneh yang terjadi. Kebijaksanaan umum adalah tidak melakukannya dengan SQL online.

Fragmentasi indeks benar-benar ortogonal ke file fragmentasi. SQL Server tidak memiliki gagasan tentang fragmentasi file - terlalu banyak lapisan virtualizatin di antaranya sehingga tidak ada harapan untuk mengerjakan geometri subsistem I / O yang sebenarnya. Namun, indeks fragmentasi, SQL tahu segalanya tentang. Tanpa mengulangi diri saya sendiri terlalu banyak dari jawaban yang telah Anda referensikan, indeks fragmentasi akan mencegah SQL melakukan read -ead range-scan efisien, terlepas dari seberapa terfragmentasi (atau tidak) file pada tingkat sistem file. Jadi - tentu saja Anda harus mengurangi fragmentasi indeks jika Anda melihat penurunan kinerja kueri.

Anda tidak harus melakukan ini dalam urutan tertentu, meskipun jika Anda menjaga fragmentasi sistem file dan kemudian membangun kembali semua indeks Anda dan menyebabkan lebih banyak fragmentasi sistem file dengan menumbuhkan banyak file pada volume defrag, Anda mungkin akan dicentang Akankah hal itu menyebabkan masalah perf? Seperti dibahas di atas, itu tergantung :-D

Semoga ini membantu!

Paul Randal
sumber
Ah, jadi apakah fragmentasi indeks internal benar-benar mengubah perilaku pengoptimal, untuk mendukung pemindaian penuh alih-alih mencari rentang indeks yang tepat?
BradC
Tidak. Pengoptimal tidak memiliki pengetahuan tentang bagaimana data disimpan dalam disk, terlepas dari fakta bahwa indeks ada, ukurannya, dan statistik distribusi nilai kolom. Ini adalah Storage Engine yang mendorong readahead dan mengubah ukuran I / O individu berdasarkan pada fragmentasi logis dari apa itu pemindaian.
Paul Randal
3

Apa cara terbaik untuk memperbaiki fragmentasi file fisik pada kotak SQL produksi?

Saya menjalankan contig SYSINTERNALS pada file database saya.

Lihat http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx

Vincent Buck
sumber
Terlihat menarik. Saya berasumsi karena menggunakan API defrag Windows, bahwa layanan SQL harus dimatikan? Atau apakah ini akan berjalan ketika server / database sedang online?
BradC
Saya telah menggunakannya dengan sukses pada database MSSQL Server online. Tapi bisa dibilang itu adalah lalu lintas rendah dan basis data kecil (kurang dari 10Gb)
Vincent Buck
Ini adalah alat yang hebat! Saya pikir itu aplikasi untuk database sangat terbatas, seperti yang disebutkan oleh orang lain, tapi saya suka untuk jenis drive lain. Mode analisis -a aman saat semuanya berjalan. Saya tidak akan merasa aman menjalankannya terhadap drive milik SQL Server langsung sekalipun.
Kendra
2

Saya akan merekomendasikan ukuran db tepat, mematikan server sql, menyalin file database ke array disk lain, dan kemudian menyalinnya kembali untuk defrag itu. Jauh lebih cepat daripada menggunakan windows defrag dalam pengalaman saya.


sumber
1

Saya mencoba untuk defragment disk fisik dalam solusi scsi sekali, tetapi mendapat sedikit atau tidak ada peningkatan kinerja sama sekali. Pelajaran yang saya pelajari adalah bahwa jika Anda mengalami kinerja yang lambat karena sistem disk, itu tidak ada hubungannya dengan fragmentasi, sejauh kita berbicara file data, karena menggunakan akses acak.

Jika indeks Anda didefragmentasi dan statistik diperbarui (sangat penting) dan Anda masih melihat I / O sebagai hambatan, maka Anda menderita hal-hal lain selain fragmentasi fisik. Sudahkah Anda menggunakan lebih dari 80% drive? Apakah Anda memiliki cukup drive? Apakah pertanyaan Anda cukup dioptimalkan? Apakah Anda melakukan banyak pemindaian Tabel atau bahkan lebih buruk banyak pencarian indeks diikuti oleh pencarian indeks berkerumun? Lihat paket kueri dan gunakan "atur statistik io on" untuk mencari tahu apa yang sebenarnya terjadi dengan kueri Anda. (mencari sejumlah besar bacaan logis atau fisik)

Tolong beri tahu saya jika saya benar-benar salah.

/ Håkan Winther

Hakan Winther
sumber
Tidak, kamu tidak salah. Tetapi mencoba untuk melakukan beberapa perbaikan di seluruh server (jika mungkin) sedikit lebih menarik daripada mulai menyelam ke dalam 150.000 pernyataan SQL berbeda yang dieksekusi selama pekerjaan analisis mingguan (tidak berlebihan. Mungkin pernyataan yang meremehkan, sebenarnya)
BradC
Jika Anda memiliki situasi seperti itu, saya akan merekomendasikan Veritas I3 untuk menganalisis lingkungan Anda untuk melihat kemacetan yang Anda alami dan apa yang menyebabkan kemacetan. Veritas I3 melacak semua pernyataan dan seberapa sering mereka dipanggil dan berapa biayanya. Ini adalah perangkat lunak yang sangat baik.
Hakan Winther
1

Mungkin indeks tidak cukup dioptimalkan untuk aplikasi Anda dan Anda tidak memiliki Veritas I3 untuk mengoptimalkan database Anda maka Anda bisa menggunakan pernyataan seperti ini untuk menemukan indeks yang hilang:

       SELECT
      mid.statement,
      mid.equality_columns,
      mid.inequality_columns,
      mid.included_columns,
      migs.user_seeks,
      migs.user_scans,
      migs.last_user_seek,
      migs.avg_user_impact,
      user_scans,
      avg_total_user_cost,
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) AS [weight]--, migs.*--, mid.*
   FROM
      sys.dm_db_missing_index_group_stats AS migs
      INNER JOIN sys.dm_db_missing_index_groups AS mig
         ON (migs.group_handle = mig.index_group_handle)
      INNER JOIN sys.dm_db_missing_index_details AS mid
         ON (mig.index_handle = mid.index_handle)
   ORDER BY
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) DESC ;

Atau pernyataan seperti ini untuk menemukan indeks yang tidak digunakan dalam pernyataan pilih dan mengurangi pembaruan / masukkan kinerja:

    CREATE PROCEDURE [ADMIN].[spIndexCostBenefit]
    @dbname [nvarchar](75)
WITH EXECUTE AS CALLER
AS
--set @dbname='Chess'
declare @dbid nvarchar(5)
declare @sql nvarchar(2000)
select @dbid = convert(nvarchar(5),db_id(@dbname))

set @sql=N'select ''object'' = t.name,i.name
        ,''user reads'' = iu.user_seeks + iu.user_scans + iu.user_lookups
        ,''system reads'' = iu.system_seeks + iu.system_scans + iu.system_lookups
        ,''user writes'' = iu.user_updates
        ,''system writes'' = iu.system_updates
from '+ @dbname + '.sys.dm_db_index_usage_stats iu
,' + @dbname + '.sys.indexes i
,' + @dbname + '.sys.tables t
where 
    iu.database_id = ' + @dbid + '
and iu.index_id=i.index_id
and iu.object_id=i.object_id
and iu.object_id=t.object_id
AND (iu.user_seeks + iu.user_scans + iu.user_lookups)<iu.user_updates
order by ''user reads'' desc'

exec sp_executesql @sql

set @sql=N'SELECT
   ''object'' = t.name,
   o.index_id,
   ''usage_reads'' = user_seeks + user_scans + user_lookups,
   ''operational_reads'' = range_scan_count + singleton_lookup_count,
   range_scan_count,
   singleton_lookup_count,
   ''usage writes'' = user_updates,
   ''operational_leaf_writes'' = leaf_insert_count + leaf_update_count + leaf_delete_count,
   leaf_insert_count,
   leaf_update_count,
   leaf_delete_count,
   ''operational_leaf_page_splits'' = leaf_allocation_count,
   ''operational_nonleaf_writes'' = nonleaf_insert_count + nonleaf_update_count + nonleaf_delete_count,
   ''operational_nonleaf_page_splits'' = nonleaf_allocation_count
FROM
   ' + @dbname + '.sys.dm_db_index_operational_stats(' + @dbid + ', NULL, NULL, NULL) o,
   ' + @dbname + '.sys.dm_db_index_usage_stats u,
    ' + @dbname + '.sys.tables t
WHERE
   u.object_id = o.object_id
   AND u.index_id = o.index_id
    and u.object_id=t.object_id
ORDER BY
   operational_reads DESC,
   operational_leaf_writes,
   operational_nonleaf_writes'

exec sp_executesql @sql

GO

Saya punya beberapa pernyataan SQL lain yang saya gunakan ketika saya menganalisis masalah kinerja di lingkungan produksi, tetapi saya pikir ini adalah awal yang baik.

(Saya tahu, Posting ini sedikit topik, tapi saya pikir Anda mungkin tertarik karena ini ada hubungannya dengan strategi pengindeksan)

/ Håkan Winther

Hakan Winther
sumber
Skrip yang bagus, saya punya beberapa yang sangat mirip. Sayangnya, kami masih 40% SQL 2000 (termasuk server yang dimaksud), yang tidak memiliki setara dengan DMV "indeks hilang" ini.
BradC
Begitu ya, saya sarankan Anda untuk melihat Veritas I3. Ini adalah produk luar biasa yang dapat Anda gunakan untuk menyetel basis data Anda, tetapi ini bukan perangkat lunak yang murah.
Hakan Winther