Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Ghi nhật ký tối thiểu với INSERT… CHỌN và Ngữ cảnh tải nhanh

Bài đăng này cung cấp thông tin mới về các điều kiện tiên quyết đối với tải số lượng lớn được ghi nhật ký tối thiểu khi sử dụng INSERT...SELECT vào bảng được lập chỉ mục .

Cơ sở nội bộ cho phép các trường hợp này được gọi là FastLoadContext . Nó có thể được kích hoạt từ SQL Server 2008 đến 2014 bao gồm cả cờ theo dõi được ghi lại 610. Từ SQL Server 2016 trở đi, FastLoadContext được bật theo mặc định; cờ theo dõi là không bắt buộc.

Không có FastLoadContext , chỉ mục chèn có thể được ghi nhật ký tối thiểu những cái đó thành một trống rỗng chỉ mục nhóm không có chỉ mục phụ, như được đề cập trong phần hai của loạt bài này. ghi nhật ký tối thiểu các điều kiện cho bảng heap không lập chỉ mục đã được đề cập trong phần một.

Để biết thêm thông tin cơ bản, hãy xem Hướng dẫn tải hiệu suất dữ liệu và Đội hổ ghi chú về các thay đổi hành vi đối với SQL Server 2016.

Bối cảnh tải nhanh

Xin nhắc lại nhanh, RowsetBulk cơ sở (được đề cập trong phần 1 và 2) cho phép ghi nhật ký tối thiểu tải số lượng lớn cho:

  • heap rỗng và không trống bảng với:
    • Khóa bảng; và
    • Không có chỉ mục phụ.
  • Các bảng được nhóm trống , với:
    • Khóa bảng; và
    • Không có chỉ mục phụ; và
    • DMLRequestSort=true trên Chèn chỉ mục theo cụm toán tử.

FastLoadContext đường dẫn mã bổ sung hỗ trợ cho ghi nhật ký tối thiểu đồng thời tải hàng loạt trên:

  • Rỗng và không rỗng được nhóm chỉ mục b-cây.
  • Rỗng và không rỗng không bao gồm chỉ mục b-cây được duy trì bởi một chuyên dụng Chèn chỉ mục nhà điều hành kế hoạch.

FastLoadContext cũng yêu cầu DMLRequestSort=true trên nhà điều hành gói tương ứng trong mọi trường hợp.

Bạn có thể nhận thấy sự trùng lặp giữa RowsetBulkFastLoadContext cho các bảng được phân nhóm trống không có chỉ mục phụ. A TABLOCK gợi ý là không bắt buộc với FastLoadContext nhưng không bắt buộc phải vắng mặt hoặc. Do đó, một chèn phù hợp với TABLOCK vẫn có thể đủ điều kiện cho ghi nhật ký tối thiểu qua FastLoadContext nếu nó không thành công RowsetBulk chi tiết kiểm tra.

FastLoadContext có thể bị vô hiệu hóa trên SQL Server 2016 bằng cách sử dụng cờ theo dõi được tài liệu hóa 692. Sự kiện mở rộng kênh gỡ lỗi fastloadcontext_enabled có thể được sử dụng để theo dõi FastLoadContext sử dụng trên mỗi phân vùng chỉ mục (tập hợp hàng). Sự kiện này không kích hoạt cho RowsetBulk tải.

Ghi nhật ký hỗn hợp

Một INSERT...SELECT duy nhất câu lệnh sử dụng FastLoadContext có thể ghi nhật ký đầy đủ một số hàng trong khi ghi nhật ký tối thiểu những người khác.

Các hàng được chèn từng hàng một bởi Chèn chỉ mục nhà điều hành và đã ghi đầy đủ trong các trường hợp sau:

  • Tất cả các hàng được thêm vào đầu tiên trang chỉ mục, nếu chỉ mục trống khi bắt đầu hoạt động.
  • Các hàng đã được thêm vào hiện có các trang chỉ mục.
  • Hàng đã di chuyển giữa các trang bằng cách tách trang.

Nếu không, các hàng từ luồng chèn theo thứ tự sẽ được thêm vào trang hoàn toàn mới sử dụng tối ưu hóa và ghi nhật ký tối thiểu đường dẫn mã. Khi càng nhiều hàng càng tốt được ghi vào trang mới, nó sẽ được liên kết trực tiếp vào cấu trúc chỉ mục mục tiêu hiện có.

Trang mới được thêm vào sẽ không nhất thiết phải đầy (mặc dù rõ ràng đó là trường hợp lý tưởng) vì SQL Server phải cẩn thận để không thêm hàng vào trang mới thuộc về một cách hợp lý trên một hiện có trang mục lục. Trang mới sẽ được 'ghép vào' chỉ mục dưới dạng một đơn vị, vì vậy chúng tôi không thể có bất kỳ hàng nào trên trang mới thuộc về nơi khác. Đây chủ yếu là một vấn đề khi thêm hàng trong phạm vi khóa chỉ mục hiện có, thay vì trước khi bắt đầu hoặc sau khi kết thúc phạm vi khóa chỉ mục hiện có.

Nó vẫn có thể để thêm các trang mới trong phạm vi khóa chỉ mục hiện tại, nhưng các hàng mới phải sắp xếp cao hơn khóa cao nhất trên trước trang chỉ mục hiện có sắp xếp thấp hơn khóa thấp nhất trên sau trang chỉ mục hiện có. Để có cơ hội tốt nhất đạt được ghi nhật ký tối thiểu trong những trường hợp này, hãy đảm bảo các hàng được chèn không trùng lặp với các hàng hiện có càng nhiều càng tốt.

Điều kiện DMLRequestSort

Hãy nhớ rằng FastLoadContext chỉ có thể được kích hoạt nếu DMLRequestSort được đặt thành true cho Chèn chỉ mục tương ứng trong kế hoạch thực thi.

Có hai đường dẫn mã chính có thể đặt DMLRequestSort thành đúng để chèn chỉ mục. Một trong hai con đường trả về true là đủ.

1. FOptimizeInsert

sqllang!CUpdUtil::FOptimizeInsert mã yêu cầu:

  • Hơn 250 hàng ước tính được chèn vào;
  • Nhiều hơn 2 trang ước tính chèn kích thước dữ liệu;
  • Chỉ mục mục tiêu phải có ít hơn 3 trang lá .

Các điều kiện này giống với RowsetBulk trên một chỉ mục được phân nhóm trống, với yêu cầu bổ sung cho không quá hai trang cấp lá chỉ mục. Lưu ý cẩn thận rằng điều này đề cập đến kích thước của chỉ mục hiện có trước khi chèn, không kích thước ước tính của dữ liệu sẽ được thêm vào.

Tập lệnh dưới đây là bản sửa đổi của bản trình diễn được sử dụng trong các phần trước của loạt bài này. Nó hiển thị ghi nhật ký tối thiểu khi ít hơn ba trang chỉ mục được điền trước kiểm tra INSERT...SELECT chạy. Lược đồ bảng kiểm tra sao cho 130 hàng có thể vừa trên một trang 8KB khi tắt phiên bản hàng cho cơ sở dữ liệu. Hệ số trong TOP đầu tiên mệnh đề có thể được thay đổi để xác định số lượng trang chỉ mục hiện có trước đó kiểm tra INSERT...SELECT được thực thi:

IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Test;
END;
GO
CREATE TABLE dbo.Test 
(
    id integer NOT NULL IDENTITY
        CONSTRAINT [PK dbo.Test (id)]
        PRIMARY KEY,
    c1 integer NOT NULL,
    padding char(45) NOT NULL
        DEFAULT ''
);
GO
-- 130 rows per page for this table 
-- structure with row versioning off
INSERT dbo.Test
    (c1)
SELECT TOP (3 * 130)    -- Change the 3 here
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV;
GO
-- Show physical index statistics
-- to confirm the number of pages
SELECT
    DDIPS.index_type_desc,
    DDIPS.alloc_unit_type_desc,
    DDIPS.page_count,
    DDIPS.record_count,
    DDIPS.avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats
(
    DB_ID(), 
    OBJECT_ID(N'dbo.Test', N'U'), 
    1,      -- Index ID
    NULL,   -- Partition ID
    'DETAILED'
) AS DDIPS
WHERE
    DDIPS.index_level = 0;  -- leaf level only
GO
-- Clear the plan cache
DBCC FREEPROCCACHE;
GO
-- Clear the log
CHECKPOINT;
GO
-- Main test
INSERT dbo.Test
    (c1)
SELECT TOP (269)
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV;
GO
-- Show log entries
SELECT
    FD.Operation,
    FD.Context,
    FD.[Log Record Length],
    FD.[Log Reserve],
    FD.AllocUnitName,
    FD.[Transaction Name],
    FD.[Lock Information],
    FD.[Description]
FROM sys.fn_dblog(NULL, NULL) AS FD;
GO
-- Count the number of  fully-logged rows
SELECT 
    [Fully Logged Rows] = COUNT_BIG(*) 
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE 
    FD.Operation = N'LOP_INSERT_ROWS'
    AND FD.Context = N'LCX_CLUSTERED'
    AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)';
GO

Khi chỉ mục được nhóm được tải trước với 3 trang , phụ trang thử nghiệm được ghi nhật ký đầy đủ (lược bỏ các bản ghi chi tiết nhật ký giao dịch cho ngắn gọn):

Khi bảng được tải trước chỉ 1 hoặc 2 trang , phụ trang thử nghiệm được ghi nhật ký tối thiểu :

Khi bảng không được tải trước với bất kỳ trang nào, kiểm tra tương đương với việc chạy bản trình diễn bảng nhóm trống từ phần hai, nhưng không có TABLOCK gợi ý:

130 hàng đầu tiên được ghi nhật ký đầy đủ . Điều này là do chỉ mục trống trước khi chúng tôi bắt đầu và 130 hàng vừa với trang đầu tiên. Hãy nhớ rằng trang đầu tiên luôn được ghi lại đầy đủ khi FastLoadContext được sử dụng và chỉ mục trống trước đó. 139 hàng còn lại được chèn với ghi nhật ký tối thiểu .

Nếu một TABLOCK gợi ý được thêm vào phần chèn, tất cả các trang được ghi nhật ký tối thiểu (bao gồm cả lần đầu tiên) vì tải chỉ mục được phân cụm trống hiện đủ điều kiện cho RowsetBulk cơ chế (với chi phí lấy Sch-M khóa).

2. FDemandRowsSortedForPerformance

Nếu FOptimizeInsert kiểm tra không thành công, DMLRequestSort vẫn có thể được đặt thành true bởi tập hợp các bài kiểm tra thứ hai trong sqllang!CUpdUtil::FDemandRowsSortedForPerformance mã số. Các điều kiện này phức tạp hơn một chút, vì vậy sẽ hữu ích khi xác định một số tham số:

  • P - số trang cấp lá hiện có trong chỉ mục mục tiêu .
  • I - ước tính số hàng cần chèn.
  • R =P / I (các trang mục tiêu trên mỗi hàng được chèn).
  • T - số lượng phân vùng đích (1 phân vùng chưa được phân vùng).

Logic để xác định giá trị của DMLRequestSort sau đó là:

  • Nếu P <= 16 trả về false , nếu không thì :
    • Nếu R < 8 :
      • Nếu P > 524 trả về true , nếu không thì false .
    • Nếu R >= 8 :
      • Nếu T > 1I > 250 trả về true , nếu không thì false .

Các bài kiểm tra trên được đánh giá bởi bộ xử lý truy vấn trong quá trình biên dịch kế hoạch. Có một điều kiện cuối cùng được đánh giá bằng mã công cụ lưu trữ (IndexDataSetSession::WakeUpInternal ) tại thời điểm thực hiện:

  • DMLRequestSort hiện tại là true ;
  • I >= 100 .

Tiếp theo, chúng tôi sẽ chia nhỏ tất cả logic này thành các phần có thể quản lý được.

Hơn 16 trang mục tiêu hiện có

Bài kiểm tra đầu tiên P <= 16 có nghĩa là các chỉ mục có ít hơn 17 trang lá hiện có sẽ không đủ điều kiện cho FastLoadContext thông qua đường dẫn mã này. Để hoàn toàn rõ ràng về điểm này, P là số trang cấp độ lá trong chỉ mục mục tiêu trước đó INSERT...SELECT được thực thi.

Để chứng minh phần logic này, chúng tôi sẽ tải trước bảng nhóm thử nghiệm có 16 trang Dữ liệu. Điều này có hai tác dụng quan trọng (hãy nhớ cả hai đường dẫn mã phải trả về false kết thúc bằng false giá trị cho DMLRequestSort ):

  1. Nó đảm bảo rằng FOptimizeInsert trước đó kiểm tra không thành công , bởi vì điều kiện thứ ba không được đáp ứng (P < 3 ).
  2. P <= 16 điều kiện trong FDemandRowsSortedForPerformance cũng sẽ không được đáp ứng.

Do đó, chúng tôi mong đợi FastLoadContext không được kích hoạt. Tập lệnh demo đã sửa đổi là:

IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Test;
END;
GO
CREATE TABLE dbo.Test 
(
    id integer NOT NULL IDENTITY
        CONSTRAINT [PK dbo.Test (id)]
        PRIMARY KEY,
    c1 integer NOT NULL,
    padding char(45) NOT NULL
        DEFAULT ''
);
GO
-- 130 rows per page for this table 
-- structure with row versioning off
INSERT dbo.Test
    (c1)
SELECT TOP (16 * 130) -- 16 pages
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV;
GO
-- Show physical index statistics
-- to confirm the number of pages
SELECT
    DDIPS.index_type_desc,
    DDIPS.alloc_unit_type_desc,
    DDIPS.page_count,
    DDIPS.record_count,
    DDIPS.avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats
(
    DB_ID(), 
    OBJECT_ID(N'dbo.Test', N'U'), 
    1,      -- Index ID
    NULL,   -- Partition ID
    'DETAILED'
) AS DDIPS
WHERE
    DDIPS.index_level = 0;  -- leaf level only
GO
-- Clear the plan cache
DBCC FREEPROCCACHE;
GO
-- Clear the log
CHECKPOINT;
GO
-- Main test
INSERT dbo.Test
    (c1)
SELECT TOP (269)
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV1
CROSS JOIN master.dbo.spt_values AS SV2;
GO
-- Show log entries
SELECT
    FD.Operation,
    FD.Context,
    FD.[Log Record Length],
    FD.[Log Reserve],
    FD.AllocUnitName,
    FD.[Transaction Name],
    FD.[Lock Information],
    FD.[Description]
FROM sys.fn_dblog(NULL, NULL) AS FD;
GO
-- Count the number of  fully-logged rows
SELECT 
    [Fully Logged Rows] = COUNT_BIG(*) 
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE 
    FD.Operation = N'LOP_INSERT_ROWS'
    AND FD.Context = N'LCX_CLUSTERED'
    AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)';

Tất cả 269 hàng đều được ghi nhật ký đầy đủ như dự đoán:

Lưu ý rằng bất kể chúng tôi đặt số lượng hàng mới để chèn cao bao nhiêu, tập lệnh ở trên sẽ không bao giờ sản xuất ghi nhật ký tối thiểu P <= 16 kiểm tra (và P < 3 kiểm tra trong FOptimizeInsert ).

Nếu bạn chọn tự chạy bản demo với số lượng hàng lớn hơn, hãy bình luận phần hiển thị các bản ghi nhật ký giao dịch riêng lẻ, nếu không, bạn sẽ phải đợi rất lâu và SSMS có thể bị lỗi. (Công bằng mà nói, dù sao nó cũng có thể làm được điều đó, nhưng tại sao lại thêm rủi ro.)

Tỷ lệ số trang trên mỗi hàng được chèn

Nếu có 17 trở lên trang lá trong chỉ mục hiện có, P <= 16 trước đó thử nghiệm sẽ không thất bại. Phần logic tiếp theo đề cập đến tỷ lệ trang hiện có đến hàng mới được chèn . Điều này cũng phải vượt qua để đạt được ghi nhật ký tối thiểu . Xin nhắc lại, các điều kiện liên quan là:

  • Tỷ lệ R =P / I .
  • Nếu R < 8 :
    • Nếu P > 524 trả về true , nếu không thì false .

Chúng ta cũng phải nhớ kiểm tra công cụ lưu trữ cuối cùng cho ít nhất 100 hàng:

  • I >= 100 .

Tổ chức lại các điều kiện đó một chút, tất cả những điều sau đây phải đúng:

  1. P > 524 (các trang chỉ mục hiện có)
  2. I >= 100 (các hàng được chèn ước tính)
  3. P / I < 8 (tỷ lệ R )

Có nhiều cách để đáp ứng ba điều kiện đó đồng thời. Hãy chọn các giá trị tối thiểu có thể có cho P (525) và I (100) đưa ra một R giá trị của (525/100) =5,25. Điều này đáp ứng (R < 8 thử nghiệm), vì vậy chúng tôi hy vọng sự kết hợp này sẽ dẫn đến ghi nhật ký tối thiểu :

IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Test;
END;
GO
CREATE TABLE dbo.Test 
(
    id integer NOT NULL IDENTITY
        CONSTRAINT [PK dbo.Test (id)]
        PRIMARY KEY,
    c1 integer NOT NULL,
    padding char(45) NOT NULL
        DEFAULT ''
);
GO
-- 130 rows per page for this table 
-- structure with row versioning off
INSERT dbo.Test
    (c1)
SELECT TOP (525 * 130) -- 525 pages
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV1
CROSS JOIN master.dbo.spt_values AS SV2;
GO
-- Show physical index statistics
-- to confirm the number of pages
SELECT
    DDIPS.index_type_desc,
    DDIPS.alloc_unit_type_desc,
    DDIPS.page_count,
    DDIPS.record_count,
    DDIPS.avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats
(
    DB_ID(), 
    OBJECT_ID(N'dbo.Test', N'U'), 
    1,      -- Index ID
    NULL,   -- Partition ID
    'DETAILED'
) AS DDIPS
WHERE
    DDIPS.index_level = 0;  -- leaf level only
GO
-- Clear the plan cache
DBCC FREEPROCCACHE;
GO
-- Clear the log
CHECKPOINT;
GO
-- Main test
INSERT dbo.Test
    (c1)
SELECT TOP (100)
    CHECKSUM(NEWID())
FROM master.dbo.spt_values AS SV1
CROSS JOIN master.dbo.spt_values AS SV2;
GO
-- Show log entries
SELECT
    FD.Operation,
    FD.Context,
    FD.[Log Record Length],
    FD.[Log Reserve],
    FD.AllocUnitName,
    FD.[Transaction Name],
    FD.[Lock Information],
    FD.[Description]
FROM sys.fn_dblog(NULL, NULL) AS FD;
GO
-- Count the number of  fully-logged rows
SELECT 
    [Fully Logged Rows] = COUNT_BIG(*) 
FROM sys.fn_dblog(NULL, NULL) AS FD
WHERE 
    FD.Operation = N'LOP_INSERT_ROWS'
    AND FD.Context = N'LCX_CLUSTERED'
    AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)';

100 hàng INSERT...SELECT thực sự là ghi nhật ký tối thiểu :

Giảm ước tính đã chèn các hàng vào 99 (ngắt I >= 100 ), và / hoặc giảm số lượng trang chỉ mục hiện có xuống còn 524 (ngắt P > 524 ) dẫn đến ghi nhật ký đầy đủ . Chúng tôi cũng có thể thực hiện các thay đổi sao cho R không còn ít hơn 8 để tạo ra ghi nhật ký đầy đủ . Ví dụ:đặt P = 1000I = 125 đưa ra R = 8 , với các kết quả sau:

125 hàng được chèn đã được ghi nhật ký đầy đủ như mong đợi. (Điều này không phải do ghi nhật ký đầy đủ trang đầu tiên, vì trước đó chỉ mục không có sản phẩm nào.)

Tỷ lệ trang cho các chỉ mục được phân vùng

Nếu tất cả các thử nghiệm trước đó không thành công, một thử nghiệm còn lại yêu cầu R >= 8 chỉ có thể hài lòng khi số lượng phân vùng (T ) lớn hơn 1 có hơn 250 ước tính các hàng được chèn (I ). Nhớ lại:

  • Nếu R >= 8 :
    • Nếu T > 1I > 250 trả về true , nếu không thì false .

Một sự tinh tế:Đối với phân vùng chỉ mục, quy tắc cho biết tất cả các hàng của trang đầu tiên được ghi lại đầy đủ (đối với chỉ mục trống ban đầu) áp dụng cho mỗi phân vùng . Đối với một đối tượng có 15.000 phân vùng, điều đó có nghĩa là 15.000 trang 'đầu tiên' được ghi đầy đủ.

Tóm tắt và Kết luận

Các công thức và thứ tự đánh giá được mô tả trong phần thân dựa trên việc kiểm tra mã bằng trình gỡ lỗi. Chúng được trình bày dưới dạng biểu thị chặt chẽ thời gian và thứ tự được sử dụng trong mã thực.

Có thể sắp xếp lại và đơn giản hóa các điều kiện đó một chút, để tạo ra một bản tóm tắt ngắn gọn hơn về các yêu cầu thực tế đối với ghi nhật ký tối thiểu khi chèn vào b-tree bằng cách sử dụng INSERT...SELECT . Các biểu thức được tinh chỉnh bên dưới sử dụng ba tham số sau:

  • P =số lượng hiện có lập chỉ mục các trang cấp độ lá.
  • I = ước tính số hàng cần chèn.
  • S = ước tính chèn kích thước dữ liệu vào các trang 8KB.

Đặt hàng loạt tải

  • Sử dụng sqlmin!RowsetBulk .
  • Yêu cầu trống mục tiêu chỉ mục được phân nhóm với TABLOCK (hoặc tương đương).
  • Yêu cầu DMLRequestSort=true trên Chèn chỉ mục theo cụm toán tử.
  • DMLRequestSort được đặt true if I > 250S > 2 .
  • Tất cả các hàng được chèn đều được ghi nhật ký tối thiểu .
  • Một Sch-M khóa ngăn chặn truy cập bảng đồng thời.

Ngữ cảnh tải nhanh

  • Sử dụng sqlmin!FastLoadContext .
  • Bật tính năng ghi nhật ký tối thiểu chèn vào các chỉ mục b-tree:
    • Theo nhóm hoặc không phân nhóm.
    • Có hoặc không có khóa bàn.
    • Chỉ mục mục tiêu trống hoặc không.
  • Yêu cầu DMLRequestSort=true trên Chèn chỉ mục được liên kết nhà điều hành kế hoạch.
  • Chỉ các hàng được viết cho trang mới được tải hàng loạt và ghi nhật ký tối thiểu .
  • Trang đầu tiên của một chỉ mục trống trước đây phân vùng luôn được đăng nhập đầy đủ .
  • Tối thiểu tuyệt đối là I >= 100 .
  • Yêu cầu cờ theo dõi 610 trước SQL Server 2016.
  • Có sẵn theo mặc định từ SQL Server 2016 (cờ theo dõi 692 vô hiệu hóa).

DMLRequestSort được đặt true cho:

  • Bất kỳ chỉ mục nào (được phân vùng hoặc không) nếu:
    • I > 250P < 3S > 2; hoặc
    • I >= 100P > 524P < I * 8

Đối với chỉ các chỉ mục được phân vùng (với> 1 phân vùng), DMLRequestSort cũng được đặt true nếu:

  • I > 250P > 16P >= I * 8

Có một vài trường hợp thú vị phát sinh từ FastLoadContext đó điều kiện:

  • Tất cả chèn vào không phân vùng chỉ mục có từ 3 đến 524 (bao gồm) các trang lá hiện có sẽ được ghi lại đầy đủ bất kể số lượng và tổng kích thước của các hàng được thêm vào. Điều này sẽ ảnh hưởng rõ rệt nhất đến các phần chèn lớn đối với các bảng nhỏ (nhưng không trống).
  • Tất cả chèn vào phân vùng chỉ mục có từ 3 đến 16 các trang hiện có sẽ được ghi nhật ký đầy đủ .
  • Chèn lớn thành lớn không phân vùng chỉ mục có thể không được ghi nhật ký tối thiểu do sự bất bình đẳng P < I * 8 . Khi P lớn, một ước tính tương ứng lớn số hàng được chèn (I ) bắt buộc. Ví dụ:một chỉ mục có 8 triệu trang không thể hỗ trợ ghi nhật ký tối thiểu khi chèn 1 triệu hàng trở xuống.

Nonclustered indexes

Các cân nhắc và tính toán tương tự được áp dụng cho các chỉ mục được nhóm trong bản trình diễn áp dụng cho nonclustered chỉ mục b-cây cũng vậy, miễn là chỉ mục được duy trì bởi nhà điều hành gói chuyên dụng (a rộng hoặc mỗi chỉ mục kế hoạch). Chỉ mục không phân tán được duy trì bởi toán tử bảng cơ sở (ví dụ: Chèn chỉ mục theo cụm ) không đủ điều kiện cho FastLoadContext .

Lưu ý rằng các tham số công thức cần phải được đánh giá mới cho mỗi nonclustered toán tử chỉ mục - kích thước hàng được tính toán, số lượng trang chỉ mục hiện có và ước tính số lượng.

Nhận xét chung

Chú ý đến ước tính số lượng thấp tại Chèn chỉ mục toán tử, vì chúng sẽ ảnh hưởng đến IS thông số. Nếu không đạt đến ngưỡng do lỗi ước tính bản số, phần chèn sẽ được ghi nhật ký đầy đủ .

Hãy nhớ rằng DMLRequestSort được lưu trữ trong bộ nhớ cache với kế hoạch - nó không được đánh giá trên mỗi lần thực hiện một kế hoạch được sử dụng lại. Điều này có thể giới thiệu một dạng của Vấn đề nhạy cảm tham số nổi tiếng (còn được gọi là “đánh giá tham số”).

Giá trị của P (các trang lá chỉ mục) không được làm mới ở đầu mỗi câu lệnh. Triển khai hiện tại lưu trữ giá trị cho toàn bộ . Điều này có thể có tác dụng phụ không mong muốn. Ví dụ:TRUNCATE TABLE trong cùng một đợt dưới dạng INSERT...SELECT sẽ không đặt lại P về 0 đối với các phép tính được mô tả trong bài viết này - chúng sẽ tiếp tục sử dụng giá trị cắt bớt trước và biên dịch lại sẽ không hữu ích. Một cách giải quyết là gửi các thay đổi lớn theo từng đợt riêng biệt.

Cờ theo dõi

Có thể buộc FDemandRowsSortedForPerformance để trả về true bằng cách đặt không có giấy tờ và không được hỗ trợ cờ theo dõi 2332, như tôi đã viết trong Tối ưu hóa truy vấn T-SQL thay đổi dữ liệu. Khi TF 2332 hoạt động, số lượng hàng ước tính để chèn vẫn cần phải là ít nhất 100 . TF 2332 ảnh hưởng đến ghi nhật ký tối thiểu quyết định cho FastLoadContext chỉ (nó có hiệu quả đối với các đống được phân vùng xa như DMLRequestSort có liên quan, nhưng không ảnh hưởng đến chính heap, vì FastLoadContext chỉ áp dụng cho các chỉ mục).

A rộng / mỗi chỉ mục Hình dạng kế hoạch để duy trì chỉ mục không phân tán có thể được buộc cho các bảng lưu trữ hàng sử dụng cờ theo dõi 8790 (không được ghi lại chính thức, nhưng được đề cập trong bài viết Cơ sở kiến ​​thức cũng như trong bài viết của tôi như được liên kết cho TF2332 ở trên).

Tất cả do Sunil Agarwal từ nhóm SQL Server:

  • Tối ưu hoá Nhập hàng loạt là gì?
  • Tối ưu hoá Nhập hàng loạt (Ghi nhật ký Tối thiểu)
  • Thay đổi ghi nhật ký tối thiểu trong SQL Server 2008
  • Thay đổi ghi nhật ký tối thiểu trong SQL Server 2008 (phần 2)
  • Thay đổi ghi nhật ký tối thiểu trong SQL Server 2008 (phần 3)

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lưu trữ dữ liệu:REST so với POSIX cho Lưu trữ và HSM

  2. Làm thế nào để thêm khóa ngoại trong SQL?

  3. Mô hình Mối quan hệ Đảng. Làm thế nào để mô hình hóa các mối quan hệ

  4. Bước tới Bắt đầu Phát triển Cơ sở dữ liệu Theo hướng Thử nghiệm (TDDD)

  5. WhoIsActive Runner