Birden çok dosyadan oluşan bir dosya grubunda bir ayırma birimi içeren dosyanın tam olarak belirlenmesinin bir yolu var mı?


13

Ben bir veritabanı içinde yaşayan çeşitli HoBT (hizalanmış ve hizalanmamış) için hangi tahsis birimleri içeren hangi veritabanı dosyaları içeren ayrıntılı bir görünüm elde etmek umuyordum.

Her zaman kullandığım sorgu (aşağıya bakın), dosya grubu başına birden çok veri dosyası oluşturmaya başlayana kadar bana iyi hizmet etti ve ben sadece dosya grubu seviyesi kadar ayrıntılı nasıl elde edebileceğimi anlayabiliyorum.

select 
    SchemaName = sh.name, 
    TableName = t.name, 
    IndexName = i.name, 
    PartitionNumber = p.partition_number,
    IndexID = i.index_id,
    IndexDataspaceID = i.data_space_id,
    AllocUnitDataspaceID = au.data_space_id,
    PartitionRows = p.rows
from sys.allocation_units au
join sys.partitions p
    on au.container_id = p.partition_id
join sys.indexes i 
    on i.object_id = p.object_id
    and i.index_id = p.index_id
join sys.tables t 
    on p.object_id = t.object_id
join sys.schemas sh
    on t.schema_id = sh.schema_id
where sh.name != 'sys'
    and au.type = 2
union all 
select 
    sh.name, 
    t.name, 
    i.name, 
    p.partition_number,
    i.index_id,
    i.data_space_id,
    au.data_space_id,
    p.rows
from sys.allocation_units au
join sys.partitions p
    on au.container_id = p.hobt_id
join sys.indexes i 
    on i.object_id = p.object_id
    and i.index_id = p.index_id
join sys.tables t 
    on p.object_id = t.object_id
join sys.schemas sh
    on t.schema_id = sh.schema_id
where sh.name != 'sys'
    and au.type in (1,3)
order by t.name, i.index_id,p.partition_number;

Ancak, yalnızca bir ayırma birimi bir veri alanı ve nihayetinde bir dosya grubuyla ilişkilendirmek kadar alabilirim çünkü bir dosya grubunda birden çok dosya olduğunda bu sorgu çalışmaz. Dosya grubundaki hangi dosyanın bir ayırma birimi içerdiğini daha iyi tanımlamak için kullanabileceğim başka bir DMV veya katalog olup olmadığını bilmek istiyorum.

Bu sorunun arkasındaki soru, bölünmüş yapıları sıkıştırmanın gerçek etkilerini değerlendirmeye çalışıyorum. Bu bilgileri almak FILEPROPERTY(FileName,'SpaceUsed')için önce ve sonra dosya ve önce ve sonra kullanarak yapabileceğimi biliyorum sys.allocation_units.used_pages/128., ama alıştırma bana belirli bir ayırma birimi içeren belirli bir dosyayı tanımlayabilir miyim merak yaptı.

Yardımcı %%physloc%%olabileceği umuduyla uğraşıyordum , ama aradığım şeyi tam olarak anlamıyor. Aşağıdaki bağlantılar Aaron Bertrand tarafından sağlanmıştır :


Yanıtlar:


11

Aşağıdaki sorguyu deneyin. Önce yerel bir geçici tablo oluşturur ve sonra sys.dm_db_database_page_allocationsSQL Server 2012'de tanıtılan belgelenmemiş bir Dinamik Yönetim İşlevi (DMF) bulunan AllocationUnitID-to-FileID ilişkilendirmeleriyle doldurur (2012 öncesi sürümler için bu bilgileri alabilirsiniz DBCC IND()). Bu yerel geçici tablo daha sonra özgün sorgunun değiştirilmiş bir sürümüne birleştirilir.

Bu DMF'den alınan veriler, performans için geçici bir tabloya yerleştirilir, çünkü veritabanının boyutuna bağlı olarak, bu verilerin alınması birkaç saniyeden uzun sürebilir. DISTINCTDMF veri sayfa başına bir satır döndürür çünkü anahtar kelime kullanılır ve her ayırma birimi başına birden çok veri sayfaları vardır.

Orijinal sorgu 0 veri sayfası (genellikle ROW_OVERFLOW_DATAve LOB_DATAtürleri) olan ayırma birimleri döndürdüğünden, bu verileri özgün sorguya bıraktı . Ayrıca, total_pagesbu veri noktasını NULLVeri Dosyaları için s olan satırlarla ilişkilendirmenin daha kolay olması için alanı ekledim . 0 satırı olan Ayırma Birimleri ile ilgilenmezseniz, bunu LEFT JOINbir INNER JOIN.

IF (OBJECT_ID(N'tempdb..#AllocationsToFiles') IS NULL)
BEGIN
    -- DROP TABLE #AllocationsToFiles;
    CREATE TABLE #AllocationsToFiles
    (
      ObjectID INT NOT NULL,
      IndexID INT NOT NULL,
      PartitionID INT NOT NULL,
      RowsetID BIGINT NOT NULL,
      AllocationUnitID BIGINT NOT NULL,
      AllocatedPageFileID SMALLINT NOT NULL
    );
END;

IF (NOT EXISTS(SELECT * FROM #AllocationsToFiles))
BEGIN
  --TRUNCATE TABLE #AllocationsToFiles;
  INSERT INTO #AllocationsToFiles (ObjectID, IndexID, PartitionID, RowsetID,
                                   AllocationUnitID, AllocatedPageFileID)
    SELECT DISTINCT alloc.[object_id], alloc.[index_id], alloc.[partition_id],
           alloc.[rowset_id], alloc.[allocation_unit_id], alloc.[allocated_page_file_id]
    FROM   sys.dm_db_database_page_allocations(DB_ID(), NULL, NULL, NULL,
                                               'LIMITED') alloc
    WHERE  alloc.is_allocated = 1
    AND    alloc.is_iam_page = 0;
END;

SELECT
    SchemaName = sh.name, 
    TableName = t.name, 
    IndexName = i.name, 
    PartitionNumber = p.partition_number,
    IndexID = i.index_id,
    IndexDataspaceID = i.data_space_id,
    AllocUnitDataspaceID = au.data_space_id,
    PartitionRows = p.[rows],
    TotalPages = au.total_pages,
    AllocationUnitType = au.type_desc,
    LogicalFileName = dbf.[name],
    PhysicalFileName = dbf.[physical_name]
    --,p.[object_id], p.[partition_id], au.allocation_unit_id
FROM sys.allocation_units au
INNER JOIN sys.partitions p
        ON au.container_id = IIF(au.[type] = 2, p.[partition_id], p.[hobt_id])
INNER JOIN sys.indexes i 
        ON i.[object_id] = p.[object_id]
       AND i.index_id = p.index_id
INNER JOIN sys.tables t 
        ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas sh
        ON t.[schema_id] = sh.[schema_id]
LEFT JOIN (#AllocationsToFiles alloc
       INNER JOIN sys.database_files dbf
               ON dbf.[file_id] = alloc.AllocatedPageFileID
          ) 
        ON alloc.ObjectID = p.[object_id]
       AND alloc.IndexID = p.index_id
       AND alloc.PartitionID = p.partition_number
       AND alloc.AllocationUnitID = au.allocation_unit_id
WHERE sh.name <> N'sys'
ORDER BY t.name, i.index_id, p.partition_number;

Bu harika bir araç, teşekkürler. TotalPages sütununun dizin için toplam sayfa olduğunu belirtmek istiyorum. Sonuçlar dizin başına birden çok satır döndürdüğünde, dizin birden çok dosyaya yayılır, ancak her dosyada dizinin ne kadarını göstermez. Her satır, dosya başına değil, dizin başına toplam sayfa sayısını gösterir. ( İlk birkaç kez çalıştırdığımı düşündüm, klasörlerim dosyalar arasında mükemmel bir şekilde dengelendi, yanılmışım )
James Jenkins

1

Remus Rusanu, 21 Mayıs 2013 tarihinde bu soruya bir cevap verdi:

Bir dosya grubu, birden çok veri dosyası, her dosyadaki tabloların listesini alma

Cevabı şuydu:

Dosya grubundaki bir nesne, dosya grubundaki tüm veri dosyalarını kullanır. FG1'deki herhangi bir tablo Datafile1, Datafile2 ve Datafile3 üzerinde eşit olarak bulunur. Yerleşimi kontrol etmeniz gerekiyorsa, farklı dosya grupları oluşturmanız gerekir.


Teşekkürler. Nereye gittiğini gerçekten kontrol etmek istemiyorum, daha ziyade nereye gittiğini görmek istiyorum.
1616'da

3
Bilginize - bu, tüm dosyaların aynı anda oluşturulduğu varsayıldığında doğrudur. Dosyalar dosya grubuna eklenmişse veya diğer izleme bayrakları kullanılmışsa, tüm dosyalarda bulunmayabilir. Diyerek, ölmedi çünkü o, yanlış söylemiyorum Değişir :)
Sean Gallardy
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.