Kết quả khác nhau xây dựng lại một chỉ mục trực tuyến và ngoại tuyến


7

Tôi có một chỉ mục không phân cụm, không duy nhất trên một cột loại khóa ngoại bigint. Khi tôi xây dựng lại chỉ mục trực tuyến, phân mảnh trung bình giảm xuống còn 3%, với 2 phân đoạn và 30 trang.

Khi tôi chạy cùng một chỉ mục xây dựng lại ngoại tuyến, phân mảnh trung bình là 25%, với 4 phân đoạn và 28 trang.

Tôi nghĩ FILLFACTORlà 90. Cơ sở dữ liệu là 77GB. Tôi không phải là DBA hoặc tương tự, tôi là nhà phát triển C #, vì vậy tôi không hoàn toàn quen thuộc với tất cả các điều khoản. Không có hoạt động nào trên bảng này, điều này xảy ra trong môi trường Dev của chúng tôi.

Đây là truy vấn, với tên được điều chỉnh lại.

ALTER INDEX [IX] ON [dbo].[Table]
REBUILD WITH
(
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON, 
    ONLINE = ON, 
    SORT_IN_TEMPDB = ON
);

Điều gì có thể gây ra sự khác biệt này? Tình trạng tương tự xảy ra trên nhiều bảng.


1
@RLT nếu bạn muốn biết thêm về các chỉ mục từ quan điểm của một nhà phát triển, bạn nên kiểm tra blog của Brent Ozar tại brentozar.com/archive/2009/02/ trên
Max Vernon

Khi đọc kỹ hơn tôi nghi ngờ đây chỉ là do kích thước cực nhỏ của chỉ số của bạn.
JNK

Câu trả lời:


3

Đây không phải là một câu trả lời đầy đủ nhưng có thể di chuyển mọi thứ một chút nếu bạn muốn thử một cái gì đó tương tự và báo cáo kết quả của bạn.

Tôi không thể tái tạo chúng. Với bảng kiểm tra sau

CREATE TABLE [dbo].[Table]
(
Col BIGINT
)

CREATE NONCLUSTERED INDEX IX ON [dbo].[Table](Col)

INSERT INTO [dbo].[Table]
SELECT top 12000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values v1, master..spt_values v2

Và nhiều lần chạy đoạn script sau

USE FragTest;

DECLARE @DbccPage TABLE (
  ParentObject VARCHAR(255),
  Object       VARCHAR(255),
  Field        VARCHAR(255),
  VALUE        VARCHAR(255))

DECLARE @sp_index_info TABLE (
  PageFID         TINYINT,
  PagePID         INT,
  IAMFID          TINYINT,
  IAMPID          INT,
  ObjectID        INT,
  IndexID         TINYINT,
  PartitionNumber TINYINT,
  PartitionID     BIGINT,
  iam_chain_type  VARCHAR(30),
  PageType        TINYINT,
  IndexLevel      TINYINT,
  NextPageFID     TINYINT,
  NextPagePID     INT,
  PrevPageFID     TINYINT,
  PrevPagePID     INT,
  PRIMARY KEY (PageFID, PagePID));

DECLARE @I INT = 0

WHILE @I < 2
  BEGIN
      DECLARE @Online VARCHAR(3) = CASE
          WHEN @I = 0 THEN 'OFF'
          ELSE 'ON'
        END

      EXEC('ALTER INDEX [IX] ON [dbo].[Table]
REBUILD WITH
(
    PAD_INDEX  = OFF, 
    STATISTICS_NORECOMPUTE  = OFF, 
    ALLOW_ROW_LOCKS  = ON, 
    ALLOW_PAGE_LOCKS  = ON, 
    ONLINE = ' + @Online + ', 
    SORT_IN_TEMPDB = ON
);')

      INSERT INTO @sp_index_info
      EXEC ('DBCC IND ( FragTest, ''[dbo].[Table]'', 2)' );

      ; WITH T
           AS (SELECT *,
                      PagePID - ROW_NUMBER() OVER (PARTITION BY PageType, IndexLevel ORDER BY PagePID) AS Grp
               FROM   @sp_index_info)
      SELECT PageType,
             MIN(PagePID) AS StartPID,
             MAX(PagePID) AS EndPID,
             COUNT(*)     AS [count],
             IndexLevel
      FROM   T
      GROUP  BY Grp,
                PageType,
                IndexLevel
      ORDER  BY PageType DESC,
                StartPID

      DECLARE @DynSQL NVARCHAR(4000)

      SELECT @DynSQL = N'DBCC PAGE (FragTest, ' + LTRIM(PageFID) + ',' + LTRIM(PagePID) + ',3) WITH TABLERESULTS'
      FROM   @sp_index_info
      WHERE  PageType = 10

      INSERT INTO @DbccPage
      EXEC(@DynSQL)

      SELECT VALUE AS SinglePageAllocations
      FROM   @DbccPage
      WHERE  VALUE <> '(0:0)'
             AND Object LIKE '%IAM: Single Page Allocations%'

      SELECT avg_page_space_used_in_percent,
             avg_fragmentation_in_percent,
             fragment_count,
             page_count,
             @Online                                                   AS [Online],
             (SELECT COUNT(*)
              FROM   @DbccPage
              WHERE  VALUE <> '(0:0)'
                     AND Object LIKE '%IAM: Single Page Allocations%') AS SinglePageAllocations
      FROM   sys.dm_db_index_physical_stats(db_id(), object_id('[dbo].[Table]'), 2, NULL, 'DETAILED')
      WHERE  index_level = 0

      DELETE FROM @sp_index_info

      DELETE FROM @DbccPage

      SET @I = @I + 1
  END 

Tôi luôn có kết quả như

Trực tuyến = TẮT

PageType StartPID    EndPID      count       IndexLevel
-------- ----------- ----------- ----------- ----------
10       119         119         1           NULL
2        2328        2351        24          0
2        2352        2352        1           1
2        2384        2392        9           0


SinglePageAllocations
----------------------

(0 row(s) affected)


avg_page_space_used_in_percent avg_fragmentation_in_percent fragment_count       page_count           Online SinglePageAllocations
------------------------------ ---------------------------- -------------------- -------------------- ------ ---------------------
98.8139362490734               0                            2                    33                   OFF    0

Trực tuyến = BẬT

PageType StartPID    EndPID      count       IndexLevel
-------- ----------- ----------- ----------- ----------
10       115         115         1           NULL
2        114         114         1           0
2        118         118         1           1
2        2416        2449        34          0



SinglePageAllocations
-----------------------
(1:114)
(1:118)


avg_page_space_used_in_percent avg_fragmentation_in_percent fragment_count       page_count           Online SinglePageAllocations
------------------------------ ---------------------------- -------------------- -------------------- ------ ---------------------
97.4019644180875               2.85714285714286             2                    35                   ON     2

Ít nhất trong thử nghiệm tôi đã thực hiện sự khác biệt giữa hai phân mảnh cân bằng khôn ngoan (mặc dù tương tự như thử nghiệm của bạn, tôi thấy rằng việc xây dựng lại chỉ mục trực tuyến dẫn đến số trang cao hơn.).

Tôi thấy rằng Online = OFFphiên bản luôn sử dụng mức độ đồng đều và không có phân bổ trang đơn trong khi Online = ONdường như luôn đặt trang gốc chỉ mục và trang lá chỉ mục đầu tiên trong phạm vi hỗn hợp.

Đặt trang lá chỉ mục đầu tiên trong một phạm vi hỗn hợp và phần còn lại trong phạm vi đồng phục liền kề gây ra số lượng mảnh là 2.

Các Online = OFFphiên bản tránh đoạn gây ra bởi sự trang lá index duy nhất nhưng tiếp giáp của các trang lá bị phá vỡ bởi các trang chỉ mục gốc mà cổ phiếu các mức độ tương tự và điều này cũng có một số mảnh vỡ của 2.

Tôi đang chạy thử nghiệm trên cơ sở dữ liệu mới được tạo với 1 GB dung lượng trống và không có hoạt động đồng thời. Có lẽ Online = OFFphiên bản dễ bị phân bổ đồng thời hơn khiến cho nó được đưa ra mức độ thống nhất không liền kề.


-6

Sự phân mảnh phụ thuộc vào hệ thống tệp của bạn, cục bộ bạn có thể có hàng triệu tệp chiếm phần lớn dung lượng ổ đĩa và có một vài khoảng trống trên đĩa có thể được sử dụng để lưu trữ một số dữ liệu. Vì vậy, nếu toàn bộ dữ liệu chỉ mục không thể được lưu trữ trong một không gian, nó sẽ phân chia thành nhiều phần. Trực tuyến, bạn có thể có đĩa trống có nhiều phần không gian chưa được gán mà có thể được sử dụng để lưu trữ toàn bộ bảng hoặc chỉ mục hoặc bất cứ thứ gì khác


1
Phân mảnh chỉ mục là tương tự nhưng không liên quan cũng không phải là kết quả của phân mảnh tệp trên đĩa.
ypercubeᵀᴹ
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.