Her şeyi yeniden oluşturup yeniden düzenledikten sonra neden veritabanım hala parçalanıyor?


40

Bu T-SQL'i çalıştırarak tüm tabloları bir kerede birleştirmek için çalıştığım bir veritabanına sahibim:

SELECT 
        'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) +
        'ALTER INDEX all ON ' + name + ' REBUILD;'
    FROM sys.tables

Sonra çıktıyı kopyalayıp yeni bir sorgu penceresine yapıştırmak ve çalıştırmak. Hatam yok ama hala parçalanma var. Her iki komutu da ayrı ayrı çalıştırmayı denedim ve hala parçalanma var. Not: Bunun REORGANIZEAaron tarafından gereksiz olduğunu farkettim ve bunu otomatikleştirmek için dinamik sql kullanabileceğimin farkındayım.

Hala parçalanmaya karar vermek için bunu koştum:

SELECT * FROM 
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) 
WHERE avg_fragmentation_in_percent > 0

Ve anladım:

database_id object_id   index_id    partition_number    index_type_desc alloc_unit_type_desc    index_depth index_level avg_fragmentation_in_percent    fragment_count  avg_fragment_size_in_pages  page_count  avg_page_space_used_in_percent  record_count    ghost_record_count  version_ghost_record_count  min_record_size_in_bytes    max_record_size_in_bytes    avg_record_size_in_bytes    forwarded_record_count  compressed_page_count
85  171147655   1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   36.3636363636364    5   2.2 11  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  421576540   1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   75  7   1.14285714285714    8   NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  965578478   1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   14.7058823529412    6   5.66666666666667    34  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  1061578820  1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   40  4   1.25    5   NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  1109578991  1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   30.7692307692308    5   2.6 13  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  1205579333  2   1   NONCLUSTERED INDEX  IN_ROW_DATA 2   0   50  5   1.6 8   NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
85  1493580359  1   1   CLUSTERED INDEX IN_ROW_DATA 2   0   50  6   1.66666666666667    10  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL

Temel bir şeyi özlediğimi biliyorum ama ne olduğunu bilmiyorum.


Hangi hataları aldın? Ayrıca, aynı şeyi yeniden düzenlemeniz ve yeniden kurmanızın bir nedeni var mı?
Shawn Melton

Shawn, bir kelimeyi kaçırdığım için özür dilerim. Bende hiç hata. Neden iki komutu da koştuğumla ilgili olarak, her komutu ayrı ayrı denedikten sonra yaptım. Sorularımı güncelledim.
Justin, 23: 24'te

Yanıtlar:


38

Masalar küçücük. Tablolarınızdaki sayfa sayısı:

11, 8, 6, 5, 13, 8, 10

Toplamda 480kb işgal ediyorlar. Kelimenin tam anlamıyla birleştirecek bir şey yok.

Düzenleme: Bu biraz daha açıklama gerektirir.

Genellikle yeni bir tablo veya indeks tahsis edilir, üniform 8 metreden ziyade karışık olan ilk 8 sayfa. Bu nedenle, ilk 8 sayfanın her birinin farklı karışık uzantılardan dağıtılması mümkündür. Bu nedenle, 8 sayfa tüketen bir tablo veya indeks 8 farklı karışık uzantının her birinde 1'inden 8 fragmana sahip olabilir.

Daha yaygın olarak kullanılan birleştirme komut dosyaları (aşağıda bağlantılı birkaç örnek), bu nedenle küçük tabloları dışlama eğilimindedir. IIRC, <500 sayfa, birinde veya ikisinde. Bu boyutlarda, birleştirmeye çok az fayda vardır ve parçalanma rakamları karışık kapsam tahsisleri tarafından potansiyel olarak çarpıktır.


Tamam, başkası daha iyi bir cevaba sahip olmadıkça tatmin edicidir, ben de seninkini doğru olarak işaretleyeceğim.
Justin Dearing,

3
+1 Mark ile anlaşıldı. Gerçekten verileriniz olduğunda, parçalanma konusunda endişelenin. :-)
Aaron Bertrand

Ne dediğini tam olarak anladım. Ancak sadece meraktan uzak, bunun nedeni db motorunun bu kadar az sayfayı birleştirememesidir. Demek istediğim, bunun bir nedeni olmalı.
Thomas Stringer

3
Olamaz, ama neden rahatsız eder ki? Bunu yapmak, G / Ç üzerinde çok az etki yaratmayacak - özellikle de bu küçük tabloların hafızada olması neredeyse garantili olduğundan.
Aaron Bertrand

1
Sadece. Garip görünüyor, hepsi bu. Dizin parçalanmasını kontrol etmek ve raporlamak için bir uygulama yazıyorum, sadece parça yüzdesini değil, aynı zamanda yanlış alarm olmaması için sayfa sayısını da test etmek için ekli bir mantık eklemek zorunda kalacağım.
Thomas Stringer

18

" Microsoft SQL Server 2000 Dizin Birleştirme En İyi Uygulamaları " bölümünden alıntı :

"Parçalanma disk G / Ç'yi etkiler. Bu nedenle, sayfalarının SQL Server tarafından önbelleğe alınma olasılığı daha düşük olduğundan daha büyük dizinlere odaklanın. Dizinlerin boyutu hakkında bir fikir edinmek için DBCC SHOWCONTIG tarafından bildirilen sayfa sayısını kullanın (her sayfa 8 KB boyutunda) Genel olarak, 1.000 sayfadan daha az dizine sahip parçalanma düzeyleriyle ilgilenmemeniz gerekir.Testlerde, 10.000'den fazla sayfa içeren dizinler, performans artışlarını, büyük ölçüde daha fazla sayfa içeren dizinlerde en yüksek kazançları elde etti (daha büyük) 50.000 sayfadan fazla) . "

Yani bu tür sorunuza cevap veriyor ve Mark'ın ve Aaron'un cevaplarını destekliyor.

Endeks parçalanması hakkında iyi bilgiyi Brent Ozar'ın aşağıdaki makalelerinde bulabilirsiniz:

Ayrıca .. Genelde endeksler hakkında büyük bir bilgi okyanusu (ayrıca parçalanma sorunları hakkında) da Kimberly Tripp'in blogunda bulunabilir .


11

Bu, sorunuza cevap vermek anlamına gelmez, ancak hiçbir zaman bir yorumda bulunmayacaktır. Çıktıyı başka bir pencereye kopyalayıp yapıştırmak zorunda kalmadan bu betiği dinamik olarak oluşturabilirsiniz. Dikkate alarak kesinlikle hiçbir neden olmadığını REORGANIZEo zaman ve REBUILD:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'ALTER INDEX all ON ' + name + ' REBUILD;
    ' FROM sys.tables;

PRINT @sql; -- to see the first 8,000 characters and make sure it checks out
-- EXEC sp_executesql @sql;

Aaron, dinamik sql'yi gösterdiğin için teşekkürler, dinamik sql'nin farkındayım, işe yarayana kadar çözümü otomatikleştirmeyecektim. Bunu okuyan başkalarının muhtemelen farkında olmaları gerekir.
Justin,
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.