Có tồn tại một cách để xác định tệp chính xác có chứa một đơn vị phân bổ trong một nhóm nhiều tệp không?


13

Tôi đã hy vọng có được một cái nhìn chi tiết về các tệp cơ sở dữ liệu chứa các đơn vị phân bổ nào cho các HoBT khác nhau (cả liên kết và không liên kết) sống trong cơ sở dữ liệu.

Truy vấn tôi luôn sử dụng (xem bên dưới) đã phục vụ tốt cho đến khi chúng tôi bắt đầu tạo nhiều tệp dữ liệu cho mỗi nhóm và tôi chỉ có thể tìm ra cách để có được mức độ chi tiết như cấp độ nhóm.

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;

Tuy nhiên, truy vấn này sẽ không hoạt động khi có nhiều tệp trong một nhóm fileg vì tôi chỉ có thể liên quan đến một đơn vị phân bổ đến một không gian dữ liệu và cuối cùng là một filegroup. Tôi muốn biết nếu có một DMV hoặc danh mục khác mà tôi thiếu mà tôi có thể sử dụng để xác định thêm tập tin nào trong nhóm fileg chứa đơn vị phân bổ.

Câu hỏi đằng sau câu hỏi này là tôi đang cố gắng đánh giá hiệu quả thực tế của việc nén các cấu trúc phân vùng. Tôi biết rằng tôi có thể thực hiện trước và sau khi sử dụng FILEPROPERTY(FileName,'SpaceUsed')cho tệp và trước và sau sys.allocation_units.used_pages/128.để có được thông tin này, nhưng bản thân bài tập khiến tôi tự hỏi liệu tôi có thể xác định tệp cụ thể có chứa đơn vị phân bổ cụ thể không.

Tôi đã %%physloc%%loay hoay với hy vọng nó có thể giúp ích, nhưng nó không hoàn toàn giúp tôi tìm được thứ gì. Các liên kết dưới đây được cung cấp bởi Aaron Bertrand :


Câu trả lời:


11

Hãy thử truy vấn sau đây. Đầu tiên, nó tạo một bảng tạm thời cục bộ và sau đó điền vào bảng liên kết AllocationUnitID-FileID được tìm thấy trong sys.dm_db_database_page_allocations, một chức năng quản lý động không có giấy tờ (DMF) được giới thiệu trong SQL Server 2012 (đối với các phiên bản trước năm 2012, bạn có thể lấy thông tin này từ DBCC IND()). Bảng tạm thời cục bộ đó sau đó được THAM GIA thành một phiên bản sửa đổi của truy vấn ban đầu.

Dữ liệu từ DMF đó được đặt vào một bảng tạm thời để thực hiện vì tùy thuộc vào kích thước của cơ sở dữ liệu, có thể mất hơn vài giây để có được dữ liệu đó. Các DISTINCTtừ khóa được sử dụng bởi vì đó DMF trả về một hàng cho mỗi trang dữ liệu, và có rất nhiều trang dữ liệu cho mỗi đơn vị phân bổ.

Tôi đã bỏ lại dữ liệu đó vào truy vấn ban đầu vì truy vấn ban đầu trả về các đơn vị phân bổ có 0 trang dữ liệu (thông thường ROW_OVERFLOW_DATALOB_DATAcác loại). Tôi cũng đã thêm total_pagestrường để có thể dễ dàng liên kết điểm dữ liệu đó với các hàng có NULLs cho Tệp dữ liệu. Nếu bạn không quan tâm đến các Đơn vị phân bổ có 0 hàng, thì có thể thay đổi đó LEFT JOINthành một hàng 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;

Đây là một công cụ tuyệt vời, cảm ơn bạn. Tôi muốn chỉ ra rằng cột TotalPages, là tổng số trang cho chỉ mục. Khi kết quả trả về nhiều hàng cho mỗi chỉ mục, chỉ mục được trải đều trên nhiều tệp, nhưng nó không hiển thị bao nhiêu chỉ mục trên mỗi tệp. Mỗi hàng sẽ hiển thị tổng số trang trên mỗi chỉ mục, không phải trên mỗi tệp. ( Một vài lần đầu tiên tôi chạy nó, tôi nghĩ rằng, các chỉ số của tôi được cân bằng hoàn hảo trên các tệp, tôi đã sai )
James Jenkins

1

Remus Rusanu, vào ngày 21 tháng 5 năm 2013, đã đưa ra câu trả lời cho câu hỏi này:

Một nhóm tệp, nhiều tệp dữ liệu, làm thế nào để có được danh sách các bảng trong mỗi tệp

Câu trả lời của anh ấy là:

Một đối tượng trong nhóm fileg sẽ sử dụng tất cả các tệp dữ liệu trong filegroup. Bất kỳ bảng nào trong FG1 đều nằm trên Datafile1, Datafile2 và Datafile3. Nếu bạn cần kiểm soát vị trí, bạn cần tạo các nhóm riêng biệt.


Cảm ơn. Tôi thực sự không muốn kiểm soát nơi nó đi, mà là xem nó đi đâu.
swasheck

3
FYI - điều này đúng với giả định tất cả các tệp được tạo cùng một lúc. Nếu các tệp đã được thêm vào filegroup hoặc các cờ theo dõi khác được sử dụng, nó có thể không có trong tất cả các tệp. Không nói anh ấy sai, bởi vì anh ấy không, nói rằng điều đó phụ thuộc :)
Sean nói loại bỏ Sara Chipps
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.