Cập nhật chỉ mục duy nhất và quầy sửa đổi hàng thống kê


14

Cho bảng sau, chỉ mục cụm duy nhất và thống kê:

CREATE TABLE dbo.Banana
(
    pk integer NOT NULL, 
    c1 char(1) NOT NULL, 
    c2 char(1) NOT NULL
);

CREATE UNIQUE CLUSTERED INDEX pk ON dbo.Banana (pk);

CREATE STATISTICS c1 ON dbo.Banana (c1);
CREATE STATISTICS c2 ON dbo.Banana (c2);

INSERT dbo.Banana 
    (pk, c1, c2) 
VALUES 
    (1, 'A', 'W'), 
    (2, 'B', 'X'), 
    (3, 'C', 'Y'), 
    (4, 'D', 'Z');

-- Populate statistics
UPDATE STATISTICS dbo.Banana;

Dữ liệu mẫu

Các bộ đếm sửa đổi hàng thống kê rõ ràng hiển thị bằng không trước bất kỳ cập nhật nào:

-- Show statistics modification counters
SELECT
    stats_name = S.[name], 
    DDSP.stats_id,
    DDSP.[rows],
    DDSP.modification_counter
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.object_id, S.stats_id) AS DDSP
WHERE
    S.[object_id] = OBJECT_ID(N'dbo.Banana', N'U');

Không sửa đổi quầy

Tăng từng pkgiá trị cột cho mỗi hàng:

-- Increment pk in every row
UPDATE dbo.Banana 
SET pk += 1;

Sử dụng kế hoạch thực hiện:

Chia nhỏ Sắp xếp kế hoạch thực hiện

Nó tạo ra các bộ đếm sửa đổi thống kê sau:

Quầy sửa đổi sau cập nhật

Câu hỏi

  1. Các toán tử Split, Sắp xếp và Thu gọn làm gì?
  2. Tại sao các pksố liệu thống kê hiển thị 2 sửa đổi, nhưng c1c2hiển thị 5?

Câu trả lời:


15

SQL Server luôn sử dụng tổ hợp toán tử Tách, Sắp xếp và Thu gọn khi duy trì một chỉ mục duy nhất như là một phần của bản cập nhật ảnh hưởng (hoặc có thể ảnh hưởng) nhiều hơn một hàng.

Làm việc qua ví dụ trong câu hỏi, chúng ta có thể viết bản cập nhật dưới dạng một bản cập nhật một hàng riêng biệt cho mỗi trong bốn hàng có mặt:

-- Per row updates
UPDATE dbo.Banana SET pk = 2 WHERE pk = 1;
UPDATE dbo.Banana SET pk = 3 WHERE pk = 2;
UPDATE dbo.Banana SET pk = 4 WHERE pk = 3;
UPDATE dbo.Banana SET pk = 5 WHERE pk = 4;

Vấn đề là câu lệnh đầu tiên sẽ thất bại, vì nó thay đổi pktừ 1 thành 2 và đã có một hàng trong đó pk= 2. Công cụ lưu trữ SQL Server yêu cầu các chỉ mục duy nhất vẫn duy nhất ở mỗi giai đoạn xử lý, ngay cả trong một câu lệnh . Đây là vấn đề được giải quyết bằng Tách, Sắp xếp và Thu gọn.

Tách Tách

Bước đầu tiên là phân tách từng câu lệnh cập nhật thành một lần xóa và sau đó là chèn:

DELETE dbo.Banana WHERE pk = 1;
INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');

DELETE dbo.Banana WHERE pk = 2;
INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');

DELETE dbo.Banana WHERE pk = 3;
INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');

DELETE dbo.Banana WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');

Toán tử Split thêm một cột mã hành động vào luồng (ở đây có nhãn Act1007):

Chia thuộc tính

Mã hành động là 1 cho một bản cập nhật, 3 cho một lần xóa và 4 cho một lần chèn.

Sắp xếp Sắp xếp

Các câu lệnh phân tách ở trên vẫn sẽ tạo ra một vi phạm khóa duy nhất tạm thời sai, vì vậy bước tiếp theo là sắp xếp các câu lệnh theo các khóa của chỉ mục duy nhất được cập nhật ( pktrong trường hợp này), sau đó theo mã hành động. Trong ví dụ này, điều này chỉ có nghĩa là xóa (3) trên cùng một khóa được sắp xếp trước khi chèn (4). Thứ tự kết quả là:

-- Sort (pk, action)
DELETE dbo.Banana WHERE pk = 1;
DELETE dbo.Banana WHERE pk = 2;
INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');
DELETE dbo.Banana WHERE pk = 3;
INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');
DELETE dbo.Banana WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');

Sắp xếp các thuộc tính

Sự sụp đổ Sự sụp đổ

Giai đoạn trước là đủ để đảm bảo tránh các vi phạm duy nhất sai trong mọi trường hợp. Để tối ưu hóa, Thu gọn kết hợp xóa và chèn liền kề trên cùng một giá trị khóa vào một bản cập nhật:

-- Collapse (pk)
DELETE dbo.Banana WHERE pk = 1;
UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2;
UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3;
UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4;
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');

Các cặp xóa / chèn cho pkcác giá trị 2, 3 và 4 đã được kết hợp thành một bản cập nhật, để lại một lần xóa trên pk= 1 và chèn cho pk= 5.

Toán tử Thu gọn nhóm các hàng theo các cột chính và cập nhật mã hành động để phản ánh kết quả thu gọn:

Thu gọn tài sản

Cập nhật chỉ mục cụm Cập nhật chỉ mục cụm

Toán tử này được gắn nhãn là Cập nhật, nhưng nó có khả năng chèn, cập nhật và xóa. Hành động nào được thực hiện bởi Cập nhật chỉ mục cụm trên mỗi hàng được xác định bởi giá trị của mã hành động trong hàng đó. Toán tử có thuộc tính Action để phản ánh chế độ hoạt động này:

Thuộc tính hành động Cập nhật nhóm cụm


Quầy sửa đổi hàng

Lưu ý rằng ba bản cập nhật ở trên không sửa đổi (các) khóa của chỉ mục duy nhất đang được duy trì. Trên thực tế, chúng tôi đã chuyển đổi các bản cập nhật cho các cột chính trong chỉ mục thành các bản cập nhật của các cột không khóa ( c1c2), cộng với xóa và chèn. Không phải xóa hay chèn đều có thể gây ra vi phạm khóa duy nhất sai.

Một chèn hoặc xóa ảnh hưởng đến mỗi cột duy nhất trong hàng, do đó, số liệu thống kê được liên kết với mỗi cột sẽ tăng các bộ đếm sửa đổi của chúng. Đối với (các) bản cập nhật, chỉ các số liệu thống kê với bất kỳ cột nào được cập nhật làm cột hàng đầu có các bộ đếm sửa đổi của chúng tăng lên (ngay cả khi giá trị không thay đổi).

Do đó, bộ đếm sửa đổi hàng thống kê hiển thị 2 thay đổi pkvà 5 cho c1c2:

-- Collapse (pk)
DELETE dbo.Banana WHERE pk = 1;                         -- All columns modified
UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2;  -- c1 and c2 modified
UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3;  -- c1 and c2 modified
UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4;  -- c1 and c2 modified
INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');    -- All columns modified

Lưu ý: Chỉ những thay đổi được áp dụng cho đối tượng cơ sở (chỉ số heap hoặc cụm) mới ảnh hưởng đến các bộ đếm sửa đổi hàng thống kê. Các chỉ mục không phân cụm là các cấu trúc thứ cấp, phản ánh các thay đổi đã được thực hiện cho đối tượng cơ sở. Chúng hoàn toàn không ảnh hưởng đến các quầy sửa đổi hàng thống kê.

Nếu một đối tượng có nhiều chỉ mục duy nhất, một tổ hợp Tách, Sắp xếp, Thu gọn riêng biệt được sử dụng để tổ chức các bản cập nhật cho từng chỉ mục. SQL Server tối ưu hóa trường hợp này cho các chỉ mục không bao gồm bằng cách lưu kết quả của Spool vào Spool Table Spool, sau đó phát lại tập hợp đó cho từng chỉ mục duy nhất (sẽ có Sắp xếp riêng theo khóa chỉ mục + mã hành động và Thu gọn).

Ảnh hưởng đến cập nhật thống kê

Cập nhật thống kê tự động (nếu được bật) xảy ra khi trình tối ưu hóa truy vấn cần thông tin thống kê và thông báo rằng số liệu thống kê hiện tại đã lỗi thời (hoặc không hợp lệ do thay đổi lược đồ). Thống kê được coi là lỗi thời khi số lượng sửa đổi được ghi vượt quá ngưỡng.

Sắp xếp Tách / Sắp xếp / Thu gọn dẫn đến các sửa đổi hàng khác nhau được ghi lại hơn mong đợi. Điều này, đến lượt nó, có nghĩa là một bản cập nhật thống kê có thể được kích hoạt sớm hơn hoặc muộn hơn so với trường hợp khác.

Trong ví dụ trên, sửa đổi hàng cho cột khóa tăng thêm 2 (thay đổi ròng) thay vì 4 (một cho mỗi hàng của bảng bị ảnh hưởng) hoặc 5 (một cho mỗi lần xóa / cập nhật / chèn được tạo bởi Thu gọn).

Ngoài ra, các cột không khóa không bị thay đổi về mặt logic bởi truy vấn ban đầu sẽ tích lũy các sửa đổi hàng, có thể đánh số gấp đôi số hàng của bảng được cập nhật (một cho mỗi lần xóa và một cho mỗi lần chèn).


Số lượng thay đổi được ghi lại tùy thuộc vào mức độ chồng chéo giữa các giá trị cột khóa cũ và mới (và do đó mức độ xóa và chèn riêng biệt có thể được thu gọn). Đặt lại bảng giữa mỗi lần thực hiện, các truy vấn sau đây cho thấy hiệu ứng trên các bộ đếm sửa đổi hàng với các lớp phủ khác nhau:

UPDATE dbo.Banana SET pk = pk + 0; -- Full overlap

pk = pk + 0

UPDATE dbo.Banana SET pk = pk + 1;

pk = pk + 1

UPDATE dbo.Banana SET pk = pk + 2;

pk = pk + 2

UPDATE dbo.Banana SET pk = pk + 3;

pk = pk + 3

UPDATE dbo.Banana SET pk = pk + 4; -- No overlap

pk = pk + 4

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.