Gibt es eine Möglichkeit, die genaue Datei zu ermitteln, die eine Zuordnungseinheit in einer Dateigruppe mit mehreren Dateien enthält?

13

Ich hatte gehofft, eine granulare Ansicht zu erhalten, welche Datenbankdateien welche Zuordnungseinheiten für die verschiedenen HoBTs (sowohl ausgerichtet als auch nicht ausgerichtet) enthielten, die in einer Datenbank leben.

Die Abfrage, die ich immer verwendet habe (siehe unten), hat mir gute Dienste geleistet, bis wir angefangen haben, mehrere Datendateien pro Dateigruppe zu erstellen, und ich kann nur herausfinden, wie man so detailliert wie die Dateigruppenebene wird.

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;

Diese Abfrage funktioniert jedoch nicht, wenn eine Dateigruppe mehrere Dateien enthält, da ich nur eine Zuordnungseinheit zu einem Datenbereich und schließlich zu einer Dateigruppe herstellen kann. Ich würde gerne wissen, ob es eine andere DMV oder einen anderen Katalog gibt, mit denen ich genauer identifizieren kann, welche Datei in der Dateigruppe eine Zuordnungseinheit enthält.

Die Frage hinter dieser Frage ist, dass ich versuche, die tatsächlichen Auswirkungen der Komprimierung partitionierter Strukturen zu bewerten. Ich weiß, dass ich FILEPROPERTY(FileName,'SpaceUsed')für die Datei eine Vorher-Nachher -Verwendung und für die Datei eine Vorher-Nachher-Verwendung ausführen kann sys.allocation_units.used_pages/128., um diese Informationen abzurufen, aber die Übung selbst hat mich gefragt, ob ich die bestimmte Datei identifizieren kann, die eine bestimmte Zuordnungseinheit enthält.

Ich habe %%physloc%%in der Hoffnung herumgespielt, dass es helfen könnte, aber es bringt mich nicht ganz auf das, wonach ich suche. Die folgenden Links wurden von Aaron Bertrand bereitgestellt :

Swasheck
quelle
2
Verwandte Themen
Paul White Reinstate Monica

Antworten:

11

Versuchen Sie die folgende Abfrage. Es erstellt zunächst eine lokale temporäre Tabelle und füllt sie dann mit den Zuordnungen AllocationUnitID-to-FileID, die in sys.dm_db_database_page_allocationseiner in SQL Server 2012 eingeführten undokumentierten dynamischen Verwaltungsfunktion ( undocumented Dynamic Management Function, DMF) enthalten sind (für Versionen vor 2012 können Sie diese Informationen abrufen DBCC IND()). Diese lokale temporäre Tabelle wird dann zu einer modifizierten Version der ursprünglichen Abfrage verknüpft.

Die Daten aus diesem DMF werden zur Leistungssteigerung in eine temporäre Tabelle gestellt, da es je nach Größe der Datenbank einige Sekunden dauern kann, bis diese Daten abgerufen werden. Das DISTINCTSchlüsselwort wird verwendet, weil dieser DMF eine Zeile pro Datenseite zurückgibt und es mehrere Datenseiten pro Zuordnungseinheit gibt.

Ich habe diese Daten in der ursprünglichen Abfrage belassen, da die ursprüngliche Abfrage Zuordnungseinheiten zurückgibt, die 0 Datenseiten (normalerweise ROW_OVERFLOW_DATAund LOB_DATATypen) haben. Ich habe das total_pagesFeld auch hinzugefügt , damit es einfacher ist, diesen Datenpunkt mit den Zeilen zu verknüpfen, die NULLs für die Datendateien enthalten. Wenn Sie sich nicht für die Allocation Units interessieren, die 0 Zeilen haben, ist es in Ordnung, LEFT JOINdies in eine zu ändern 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;
Solomon Rutzky
quelle
Dies ist ein großartiges Tool, danke. Ich möchte darauf hinweisen, dass die Spalte TotalPages die Gesamtseiten für den Index darstellt. Wenn die Ergebnisse mehrere Zeilen pro Index zurückgeben, wird der Index auf mehrere Dateien verteilt, es wird jedoch nicht angezeigt, wie viel Index sich in jeder Datei befindet. Jede Zeile zeigt die Gesamtzahl der Seiten pro Index, nicht pro Datei. ( Die ersten Male, als ich es lief, dachte ich, cool, meine Indizes sind perfekt über Dateien verteilt, ich habe mich geirrt )
James Jenkins
1

Remus Rusanu gab am 21. Mai 2013 eine Antwort auf diese Frage:

Eine Dateigruppe, mehrere Datendateien, wie eine Liste von Tabellen in jeder Datei abgerufen wird

Seine Antwort war:

Ein Objekt in einer Dateigruppe verwendet alle Datendateien in der Dateigruppe. Jede Tabelle in FG1 befindet sich gleichermaßen in Datafile1, Datafile2 und Datafile3. Wenn Sie die Platzierung steuern müssen, müssen Sie unterschiedliche Dateigruppen erstellen.

RLF
quelle
Vielen Dank. Ich möchte nicht wirklich kontrollieren, wohin es geht, sondern nur sehen, wohin es geht.
Swasheck
3
Zu Ihrer Information: Dies ist unter der Annahme korrekt, dass alle Dateien gleichzeitig erstellt wurden. Wenn Dateien zur Dateigruppe hinzugefügt wurden oder andere Ablaufverfolgungsflags verwendet wurden, ist dies möglicherweise nicht in allen Dateien der Fall. Das heißt nicht, dass er sich irrt, weil er sich nicht irrt, das hängt davon ab :)
Sean sagt Entfernen Sara Chipps