Tại sao thống kê được tạo tự động trên cột này trống?


8

Thông tin

Câu hỏi của tôi liên quan đến một bảng lớn vừa phải (không gian dữ liệu ~ 40 GB) là một đống
(Thật không may, tôi không được phép thêm một chỉ mục được nhóm vào bảng bởi các chủ sở hữu ứng dụng)

Một thống kê được tạo tự động trên cột Danh tính ( ID) đã được tạo, nhưng trống.

  • Tự động tạo số liệu thống kê & tự động cập nhật số liệu thống kê được bật
  • Sửa đổi đã xảy ra trong bảng
  • Có những thống kê khác (được tạo tự động) đang được cập nhật
  • Có một thống kê khác trên cùng một cột được tạo bởi một chỉ mục (trùng lặp)
  • Bản dựng: 12.0.5546

Thống kê trùng lặp đang được cập nhật: nhập mô tả hình ảnh ở đây

Câu hỏi thực tế

Theo hiểu biết của tôi, tất cả các số liệu thống kê có thể được sử dụng và sửa đổi được theo dõi, ngay cả khi có hai số liệu thống kê trên cùng một cột (trùng lặp), vậy tại sao thống kê này vẫn trống?

Thông tin thống kê

nhập mô tả hình ảnh ở đây

Thông tin thống kê DB

nhập mô tả hình ảnh ở đây

Kích thước bảng

nhập mô tả hình ảnh ở đây

Cột Thông tin nơi thống kê được tạo trên

nhập mô tả hình ảnh ở đây

[ID] [int] IDENTITY(1,1) NOT NULL

Cột định danh

select * from sys.stats  
where name like '%_WA_Sys_0000000A_6B7099F3%';

nhập mô tả hình ảnh ở đây Tự động tạo

Nhận một số thông tin về một thống kê khác

select * From sys.dm_db_stats_properties (1802541555, 3)  

nhập mô tả hình ảnh ở đây

So với chỉ số trống của tôi:

nhập mô tả hình ảnh ở đây

Số liệu thống kê + Biểu đồ từ "tạo tập lệnh":

/****** Object:  Statistic [_WA_Sys_0000000A_6B7099F3]    Script Date: 2/1/2019 10:18:19 AM ******/

    CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

Khi tạo một bản sao của số liệu thống kê, không có dữ liệu nào bên trong

CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

nhập mô tả hình ảnh ở đây

Khi cập nhật thủ công stat họ sẽ được cập nhật.

UPDATE STATISTICS [dbo].[Table]([_WA_Sys_0000000A_6B7099F3_TEST])

nhập mô tả hình ảnh ở đây

Câu trả lời:


9

Tôi đã có thể tái tạo điều này, cả với một thống kê trống rỗng, và một thống kê dân số. Tôi đã sắp xếp một thống kê tự động được tạo trên một bảng trống và chỉ mục được tạo sau:

IF OBJECT_ID(N'dbo.Heap', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Heap;
END;
GO
CREATE TABLE dbo.Heap 
(
    id integer NOT NULL IDENTITY,
    val integer NOT NULL,
);
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Empty table
TRUNCATE TABLE dbo.Heap;
GO
-- Repeat exact same query (RT = 500 + 0.2 * 1000 = 700)
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
-- Add index
ALTER TABLE dbo.Heap ADD 
    CONSTRAINT [PK dbo.Heap id]
    PRIMARY KEY NONCLUSTERED (id);
GO
SELECT
    S.[name],
    S.auto_created,
    DDSP.stats_id,
    DDSP.last_updated,
    DDSP.[rows],
    DDSP.rows_sampled,
    DDSP.steps,
    DDSP.unfiltered_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.Heap', N'U');

Đầu ra

Tôi thấy rằng các sửa đổi tiếp tục được theo dõi chính xác trên tất cả các bản sao không trống, nhưng chỉ có một thống kê được cập nhật tự động (bất kể cài đặt không đồng bộ).

Cập nhật thống kê tự động chỉ xảy ra khi trình tối ưu hóa truy vấn cần một thống kê cụ thể và nhận thấy rằng nó đã lỗi thời (một biên dịch lại liên quan đến tối ưu).

Trình tối ưu hóa chọn từ các số liệu thống kê trùng lặp như được đề cập trong tài liệu Bộ nhớ đệm và Biên dịch lại trong SQL Server 2012 :

Một vấn đề không liên quan trực tiếp đến chủ đề của tài liệu này là: đưa ra nhiều thống kê trên cùng một tập hợp các cột theo cùng một thứ tự, làm thế nào để trình tối ưu hóa truy vấn quyết định tải cái nào trong quá trình tối ưu hóa truy vấn? Câu trả lời không đơn giản, nhưng trình tối ưu hóa truy vấn sử dụng các nguyên tắc như: Ưu tiên cho các thống kê gần đây hơn các thống kê cũ hơn; Ưu tiên cho các số liệu thống kê được tính toán bằng cách sử dụng FULLSCANtùy chọn cho những người được tính toán bằng cách sử dụng lấy mẫu; và như thế.

Vấn đề là trình tối ưu hóa chọn một trong các số liệu thống kê trùng lặp có sẵn ("tốt nhất) và một trong số đó được cập nhật tự động nếu thấy là cũ.

Tôi tin rằng đây là một thay đổi trong hành vi từ các bản phát hành cũ hơn - hoặc ít nhất là tài liệu cho thấy rằng tất cả các số liệu thống kê lỗi thời cho một đối tượng sẽ được cập nhật như một phần của quy trình này, nhưng tôi không biết khi nào điều này thay đổi. Đó chắc chắn là sau tháng 8 năm 2013 khi Matt Bowler đăng Bản sao thống kê , trong đó có một repo dựa trên AdventureWorks tiện dụng. Kịch bản đó bây giờ chỉ dẫn đến một trong các đối tượng thống kê được cập nhật, trong khi tại thời điểm cả hai.

Giải thích trên phù hợp với tất cả các hành vi tôi đã quan sát trong khi cố gắng tái tạo kịch bản của bạn, nhưng tôi nghi ngờ nó được ghi lại rõ ràng ở bất cứ đâu. Nó có vẻ như là một tối ưu hóa hợp lý, vì có rất ít giá trị trong việc giữ các bản sao được cập nhật đầy đủ.

Đây có lẽ là tất cả ở một mức độ chi tiết dưới đây mà Microsoft sẵn sàng hỗ trợ. Điều này cũng có nghĩa là nó có thể thay đổi mà không cần thông báo trước.

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.