Tôi đang kiểm tra các bản ghi nhật ký tối thiểu trong các tình huống khác nhau và từ những gì tôi đã đọc CHERTN VÀO CHỌN thành một đống với chỉ mục không được phân cụm bằng TABLOCK và SQL Server 2016+, nên đăng nhập tối thiểu, tuy nhiên trong trường hợp của tôi, tôi đang nhận được đăng nhập đầy đủ. Cơ sở dữ liệu của tôi nằm trong mô hình khôi phục đơn giản và tôi thành công nhận được các bản chèn tối thiểu được ghi vào một đống mà không có chỉ mục và TABLOCK.
Tôi đang sử dụng bản sao lưu cũ của cơ sở dữ liệu Stack Overflow để kiểm tra và đã tạo một bản sao của bảng Bài viết với lược đồ sau ...
CREATE TABLE [dbo].[PostsDestination](
[Id] [int] NOT NULL,
[AcceptedAnswerId] [int] NULL,
[AnswerCount] [int] NULL,
[Body] [nvarchar](max) NOT NULL,
[ClosedDate] [datetime] NULL,
[CommentCount] [int] NULL,
[CommunityOwnedDate] [datetime] NULL,
[CreationDate] [datetime] NOT NULL,
[FavoriteCount] [int] NULL,
[LastActivityDate] [datetime] NOT NULL,
[LastEditDate] [datetime] NULL,
[LastEditorDisplayName] [nvarchar](40) NULL,
[LastEditorUserId] [int] NULL,
[OwnerUserId] [int] NULL,
[ParentId] [int] NULL,
[PostTypeId] [int] NOT NULL,
[Score] [int] NOT NULL,
[Tags] [nvarchar](150) NULL,
[Title] [nvarchar](250) NULL,
[ViewCount] [int] NOT NULL
)
CREATE NONCLUSTERED INDEX ndx_PostsDestination_Id ON PostsDestination(Id)
Sau đó tôi cố gắng sao chép bảng bài viết vào bảng này ...
INSERT INTO PostsDestination WITH(TABLOCK)
SELECT * FROM Posts ORDER BY Id
Từ việc xem fn_dblog và cách sử dụng tệp nhật ký, tôi có thể thấy tôi không nhận được nhật ký tối thiểu từ việc này. Tôi đã đọc các phiên bản trước năm 2016 yêu cầu cờ theo dõi 610 để đăng nhập tối thiểu vào các bảng được lập chỉ mục, tôi cũng đã thử thiết lập điều này nhưng vẫn không có niềm vui.
Tôi đoán tôi đang thiếu một cái gì đó ở đây?
EDIT - Thông tin thêm
Để thêm thông tin Tôi đang sử dụng quy trình sau đây mà tôi đã viết để cố gắng phát hiện ghi nhật ký tối thiểu, có thể tôi đã gặp sự cố ở đây ...
/*
Example Usage...
EXEC sp_GetLogUseStats
@Sql = '
INSERT INTO PostsDestination
SELECT TOP 500000 * FROM Posts ORDER BY Id ',
@Schema = 'dbo',
@Table = 'PostsDestination',
@ClearData = 1
*/
CREATE PROCEDURE [dbo].[sp_GetLogUseStats]
(
@Sql NVARCHAR(400),
@Schema NVARCHAR(20),
@Table NVARCHAR(200),
@ClearData BIT = 0
)
AS
IF @ClearData = 1
BEGIN
TRUNCATE TABLE PostsDestination
END
/*Checkpoint to clear log (Assuming Simple/Bulk Recovery Model*/
CHECKPOINT
/*Snapshot of logsize before query*/
CREATE TABLE #BeforeLogUsed(
[Db] NVARCHAR(100),
LogSize NVARCHAR(30),
Used NVARCHAR(50),
Status INT
)
INSERT INTO #BeforeLogUsed
EXEC('DBCC SQLPERF(logspace)')
/*Run Query*/
EXECUTE sp_executesql @SQL
/*Snapshot of logsize after query*/
CREATE TABLE #AfterLLogUsed(
[Db] NVARCHAR(100),
LogSize NVARCHAR(30),
Used NVARCHAR(50),
Status INT
)
INSERT INTO #AfterLLogUsed
EXEC('DBCC SQLPERF(logspace)')
/*Return before and after log size*/
SELECT
CAST(#AfterLLogUsed.Used AS DECIMAL(12,4)) - CAST(#BeforeLogUsed.Used AS DECIMAL(12,4)) AS LogSpaceUsersByInsert
FROM
#BeforeLogUsed
LEFT JOIN #AfterLLogUsed ON #AfterLLogUsed.Db = #BeforeLogUsed.Db
WHERE
#BeforeLogUsed.Db = DB_NAME()
/*Get list of affected indexes from insert query*/
SELECT
@Schema + '.' + so.name + '.' + si.name AS IndexName
INTO
#IndexNames
FROM
sys.indexes si
JOIN sys.objects so ON si.[object_id] = so.[object_id]
WHERE
si.name IS NOT NULL
AND so.name = @Table
/*Insert Record For Heap*/
INSERT INTO #IndexNames VALUES(@Schema + '.' + @Table)
/*Get log recrod sizes for heap and/or any indexes*/
SELECT
AllocUnitName,
[operation],
AVG([log record length]) AvgLogLength,
SUM([log record length]) TotalLogLength,
COUNT(*) Count
INTO #LogBreakdown
FROM
fn_dblog(null, null) fn
INNER JOIN #IndexNames ON #IndexNames.IndexName = allocunitname
GROUP BY
[Operation], AllocUnitName
ORDER BY AllocUnitName, operation
SELECT * FROM #LogBreakdown
SELECT AllocUnitName, SUM(TotalLogLength) TotalLogRecordLength
FROM #LogBreakdown
GROUP BY AllocUnitName
Chèn vào một đống không có chỉ mục và TABLOCK bằng mã sau ...
EXEC sp_GetLogUseStats
@Sql = '
INSERT INTO PostsDestination
SELECT * FROM Posts ORDER BY Id ',
@Schema = 'dbo',
@Table = 'PostsDestination',
@ClearData = 1
Tôi nhận được những kết quả này
Với tốc độ tăng trưởng tệp nhật ký 0,0024mb, kích thước bản ghi nhật ký rất nhỏ và rất ít trong số đó tôi rất vui vì điều này đang sử dụng ghi nhật ký tối thiểu.
Nếu sau đó tôi tạo một chỉ mục không được nhóm trên id ...
CREATE INDEX ndx_PostsDestination_Id ON PostsDestination(Id)
Sau đó chạy lại chèn của tôi một lần nữa ...
Tôi không chỉ không nhận được đăng nhập tối thiểu vào chỉ mục không được nhóm mà tôi còn mất nó trong heap. Sau khi thực hiện thêm một số thử nghiệm, có vẻ như nếu tôi tạo ID cụm thì nó sẽ ghi nhật ký tối thiểu nhưng từ những gì tôi đã đọc 2016+ nên đăng nhập tối thiểu vào một đống với chỉ mục không được phân cụm khi sử dụng khóa tab.
EDIT CUỐI CÙNG :
Tôi đã báo cáo hành vi cho Microsoft trên SQL Server UserVoice và sẽ cập nhật nếu tôi nhận được phản hồi. Tôi cũng đã viết chi tiết đầy đủ về các kịch bản nhật ký tối thiểu mà tôi không thể làm việc tại https://gavindraper.com/2018/05/29/Query-Server-Minimal-Logging-Inserts/