SQL Veritabanı fiziksel dosya parçalanması


19

Gerçekten olduğunu biliyoruz üç parçalanma tür bir DBA olarak endişe gerektiğini:

  1. Dizin Kümelenmiş dizin (tablo) parçalanması dahil SQL veri dosyalarında parçalanma. DBCC SHOWCONTIG (SQL 2000'de) veya sys.dm_ db_ index_ fiziksel_ istatistiklerini (2005+) kullanarak tanımlayın.

  2. SQL Log dosyalarının içinde VLF Parçalanması . SQL günlük dosyalarınızın her birinde kaç VLF bulunduğunu görmek için DBCC LOGINFO'yu çalıştırın.

  3. Sabit sürücüdeki veritabanı dosyalarının fiziksel dosya parçalanması. Windows'taki "Disk Birleştiricisi" yardımcı programını kullanarak bunu tanılayın. ( bu mükemmel blog gönderisinden esinlenerek )

Dizin parçalanmasına çok dikkat edilir ( Paul Randall'ın bu mükemmel Serverfault cevabına bakın ), bu yüzden sorumun odak noktası değil.

Veritabanı başlangıçta makul bir beklenen veri dosyası ve günlük boyutu planlayarak oluşturulduğunda fiziksel parçalanmayı (ve VLF parçalanmasını) önleyebileceğimi biliyorum , çünkü bu parçalanma çoğunlukla sık sık büyür ve küçülür, ancak nasıl düzeltileceğim hakkında bazı sorularım var belirlendikten sonra fiziksel parçalanma:

  • Her şeyden önce, fiziksel parçalanma bir Kurumsal SAN'da bile geçerli mi? Bir SAN sürücüsünde Windows Birleştiricisi'ni kullanabilir miyim / kullanmalıyım mı yoksa SAN ekibi dahili birleştirme yardımcı programları mı kullanmalı? Windows sürücüsünden aldığım parçalanma analizi SAN sürücüsünde çalıştırıldığında daha doğru mu?

  • SQL performansı üzerinde fiziksel parçalanma ne kadar büyük? (Önceki sorunun sonucunu bekleyen dahili bir sürücü dizisi olduğunu varsayalım.) Dahili dizin parçalanmasından daha BÜYÜK bir anlaşma mı? Yoksa aynı türden bir sorun mu var (sürücü sıralı okumalar yerine rastgele okumalar yapmak zorunda)

  • Disk fiziksel olarak parçalanmışsa, birleştirme (veya yeniden oluşturma) dizinleri zaman kaybı mıdır? Diğerini ele almadan önce birini düzeltmem gerekiyor mu?

  • Bir üretim SQL kutusundaki fiziksel dosya parçalanmasını düzeltmenin en iyi yolu nedir? SQL hizmetlerini kapatabildiğimi ve Windows Defrag'ı çalıştırabileceğimi biliyorum, ama aynı zamanda tam bir yedekleme yaptığınız, veritabanını bıraktığınız, ardından yedeklemeden boş bir sürücüye geri yüklediğiniz bir tekniği duydum. Bu ikinci teknik tavsiye edilir mi? Böyle bir yedekten geri yükleme mu da iç endeks parçalanması ortadan kaldırarak sıfırdan inşa endeksler? Yoksa sayfa sırasını yedeklemenin çekildiği zamana mı döndürür? (Önemliyse, Quest Lightspeed yedeklerini sıkıştırma ile kullanıyoruz.)

GÜNCELLEME : SAN sürücülerinin birleştirilip birleştirilmeyeceği (NO) ve fiziksel olarak bölünmüş sürücülerde (YES) dizin birleştirmenin hala faydalı olup olmadığı konusunda şimdiye kadar iyi yanıtlar.

Başka bir kişi gerçekten birleştirme için en iyi yöntemleri tartmak ister misiniz? Veya 500GB gibi büyük bir parçalı sürücüyü birleştirmek için ne kadar bekleyeceğinizi tahmin edersiniz? Alakalı, çünkü SQL sunucumun kapanma zamanı!

Ayrıca, herhangi birinin fiziksel parçalamayı düzelterek yaptığınız SQL performans iyileştirmeleri hakkında herhangi bir anekdot bilgisi varsa, bu da harika olurdu. Mike'ın blog gönderisi sorunun çözülmesinden bahsediyor, ancak ne tür bir iyileştirme yaptığı konusunda net değil.

Yanıtlar:


9

Bence bu makale SAN sürücülerinin birleştirilmesine mükemmel bir genel bakış sunuyor

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

Temel noktalar, LUN'u sunarken konum SAN tarafından sanallaştırıldığında disk üzerindeki blokların fiziksel konumuyla ilişkilendirilmesi zor olduğundan SAN depolama biriminde birleştirmenin önerilmemesidir.

RAW aygıt eşlemeleri kullanıyorsanız veya üzerinde çalıştığınız LUN olan bir RAID setine doğrudan erişiminiz varsa, bölümlendirme işleminin olumlu bir etkiye sahip olduğunu görebiliyordum, ancak paylaşılan bir RAID'den "sanal" LUN verildiğinde 5 set, hayır.


Mükemmel makale. SAN sürücüler konusunda tam doğru.
BradC

7

Bu soru ve cevap için birden fazla bölüm:

Fiziksel dosya parçalanması, Kevin'in zaten işaret ettiği gibi Enterprise SAN depolama alanı için gerçekten önemli değildir - bu yüzden buraya eklenecek hiçbir şey yoktur. Gerçekten G / Ç alt sistemine ve tarama yaparken daha sıralı G / Ç'lere tarama yaparken sürücülerin daha rasgele G / Ç'lerden geçmesini sağlama olasılığınız azalır. DAS için, muhtemelen karmaşık bir dilim-n-zar SAN için muhtemelen değil.

Dosya sistemi düzeyinde birleştirme - yalnızca SQL kapalıyken yapın. Burada kendim hiç sorun yaşamadım (SQL veritabanı dosyalarının çevrimiçi, açık dosya dolandırıcılığını hiç yapmadım) ama garip yolsuzluk sorunlarının müşteriden ve müşterilerinden çok sayıda anekdot kanıtı duydum. Genel bilgelik çevrimiçi SQL ile yapmak değildir.

Dizin parçalanması, dosya parçalanmasına tamamen diktir. SQL Server'ın dosya parçalanması hakkında hiçbir fikri yoktur - gerçek G / Ç alt sistemi geometrilerini çalışma umuduna sahip olması için çok fazla sanallaştırıcı katman. Ancak dizin parçalanması, SQL hakkında her şeyi bilir. Kendimi daha önce başvurduğunuz yanıttan çok fazla tekrarlamadan, dizin parçalanması, dosyaların dosya sistemi düzeyinde ne kadar parçalanmış (ya da değil) olduğuna bakılmaksızın, SQL'in etkili aralık tarama readahead yapmasını engelleyecektir. Bu nedenle, sorgu performansını düşürdüğünüzü görürseniz kesinlikle dizin parçalanmasını azaltmalısınız.

Sen yok olması , dosya sistemi parçalanma özen eğer rağmen, belirli bir sırayla bunları yapabilecek ve ardından tüm dizinleri yeniden ve muhtemelen gidiyoruz bir defragged hacmine birden fazla dosya büyüyen daha fazla dosya-sistemi parçalanmasına neden işaretli olmak. Yine de mükemmel sorunlara neden olacak mı? Yukarıda tartışıldığı gibi, şunlara bağlıdır: -D

Bu yardımcı olur umarım!


Ah, dahili dizin parçalanması, uygun dizin aralığı yerine tam taramalar lehine optimize edicinin davranışını değiştirir mi?
BradC

Hayır. Optimize edici, verilerin, dizinlerin mevcut olması, boyutları ve sütun değeri dağıtım istatistikleri dışında diskte nasıl saklandığı hakkında hiçbir bilgiye sahip değildir. Okuyucunun mantıksal parçalanmasına bağlı olarak okuma başlığını çalıştıran ve tek tek G / Ç boyutlarını değiştiren Depolama Motoru.
Paul Randal

3

Bir üretim SQL kutusundaki fiziksel dosya parçalanmasını düzeltmenin en iyi yolu nedir?

Veritabanı dosyalarımda SYSINTERNALS 'contig'i çalıştırıyorum.

Bkz. Http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx


İlgi çekici görünüyor. Windows dolandırmak API'ları kullandığından, SQL hizmetlerinin kapalı olması gerektiğini varsayıyorum? Yoksa sunucu / veritabanı çevrimiçi durumdayken çalışır mı?
BradC

Çevrimiçi MSSQL Server veritabanlarında başarıyla kullandım. Ama tartışmasız bunlar düşük trafikli ve küçük veritabanlarıydı (10Gb'den az)
Vincent Buck

Bu harika bir araç! Sanırım veritabanları için yapılan uygulamalar, diğer insanlar tarafından belirtildiği gibi oldukça sınırlı, ancak diğer sürücü türleri için seviyorum. Analiz modu -a işler çalışırken güvenlidir. Gerçi canlı bir SQL Server'a ait bir sürücüye karşı çalıştırırken güvenli hissetmiyorum.
Kendra

2

Ben db uygun boyutlandırma, sql sunucusu kapatılması, veritabanı dosyasını başka bir disk dizisine kopyalamak ve daha sonra geri birleştirmek için kopya öneriyoruz. Deneyimlerime göre pencere dolandırmaktan çok daha hızlı.


1

Bir kez bir scsi çözümünde fiziksel diskleri birleştirmeye çalıştım, ancak performans artışı çok azdı ya da hiç yoktu. Öğrendiğim ders, disk sistemi nedeniyle yavaş performans elde ederseniz, rasgele erişim kullandığından veri dosyasıyla konuştuğumuz sürece, parçalanma ile ilgisi yoktur.

Dizinleriniz birleştirilirse ve istatistikler güncellenirse (çok önemli) ve hala G / Ç'yi darboğaz olarak görüyorsanız, fiziksel parçalanma dışında başka şeylerden de muzdarip olursunuz. Sürücünün% 80'inden fazlasını kullandınız mı? Yeterli diskiniz var mı? Sorgularınız yeterince optimize edildi mi? Çok fazla Tablo taraması yapıyor musunuz, hatta çok daha fazla dizin araması ve ardından kümelenmiş dizin araması yapıyor musunuz? Sorgu planlarına bakın ve sorgunuzda gerçekten neler olup bittiğini öğrenmek için "set is istatistiklerini" kullanın. (çok sayıda mantıksal veya fiziksel okuma arayın)

Tamamen yanlışsam lütfen bana bildirin.

/ Håkan Winther


Hayır, yanlış değilsin. Ancak, sunucu genelinde bazı iyileştirmeler yapmaya çalışmak (mümkünse), haftalık analiz işleri sırasında yürütülen 150.000'den fazla farklı SQL ifadesine dalmaya başlamaktan daha caziptir (abartı değil. Muhtemelen bir
eksiklik

Bu tür bir durumunuz varsa, Veritas I3'ün hangi darboğazdan muzdarip olduğunuzu ve darboğazın nedenini görmek için ortamınızı analiz etmesini öneririm. Veritas I3 tüm ifadeleri, ne sıklıkta çağrıldığını ve hangi maliyette olduğunu takip eder. Mükemmel bir yazılımdır.
Hakan Winther

1

Belki de dizinler uygulamanız için yeterince optimize edilmemiştir ve veritabanınızı optimize etmek için Veritas I3'e sahip değilseniz, eksik dizinleri bulmak için şöyle bir ifade kullanabilirsiniz:

       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 ;

Veya belirli ifadelerde kullanılmayan ve güncelleme / ekleme performansını düşüren dizinleri bulmak için şöyle bir ifade:

    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

Üretim ortamındaki performans sorunlarını analiz ederken kullandığım bazı SQL ifadeleri var, ancak bu iki bence iyi bir başlangıç.

(Biliyorum, Bu yazı biraz konu, ancak dizinleme stratejisi ile ilgili olması gerektiğinden ilginizi çekebileceğini düşündüm)

/ Håkan Winther


Mükemmel senaryolar, çok benzerim var. Ne yazık ki, hala bu "eksik dizin" DMV'lerine eşdeğer olmayan% 40 SQL 2000 (söz konusu sunucu dahil).
BradC

Anlıyorum, sonra Veritas I3'e bakmanızı tavsiye ederim. Veritabanlarınızı ayarlamak için kullanabileceğiniz mükemmel bir üründür, ancak ucuz bir yazılım değildir.
Hakan Winther
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.