Thống kê được lưu trữ vật lý trong SQL Server ở đâu?


27

Các số liệu thống kê được sử dụng bởi Trình tối ưu hóa truy vấn được lưu trữ vật lý bên trong tệp cơ sở dữ liệu SQL Server và Nhóm bộ đệm?

Cụ thể hơn, có cách nào để tìm ra các trang được sử dụng bởi thống kê sử dụng DMV và / hoặc DBCC không?

Tôi sở hữu cả SQL Server 2008 Internals và SQL Server Internals và sách khắc phục sự cố và không ai trong số chúng nói về cấu trúc vật lý của số liệu thống kê; nếu họ không tôi có thể tìm thấy thông tin này.


1
Khi bạn tạo một bản thống kê chỉ sao chép cơ sở dữ liệu, nó sẽ hiển thị một tệp nhị phân STATS_STREAMmà tôi chưa bao giờ xem xét liệu đây có phải là thứ có thể tìm thấy trong chính tệp đó không.
Martin Smith

2
Số liệu thống kê được tạo bởi một hàm tổng hợp chỉ nội bộ ( StatMan) tạo ra một blob (trớ trêu thay, tên đó được tô sáng như một hàm trong cửa sổ truy vấn SSMS). Về mặt logic, các số liệu thống kê được liên kết với một chỉ mục hoặc một tập hợp các cột trong bảng, vì vậy tôi sẽ bắt đầu bằng cách kiểm tra các bảng siêu dữ liệu nội bộ đang tìm kiếm một cột binaryhoặc varbinarycột sẽ dẫn đến blob. Điều này có thể xem được bằng cách sử dụng DBCC PAGE, nhưng có lẽ không phải là bất kỳ cách nào khác bởi vì đó là tất cả nội bộ.
Jon Seigel

1
@ivanmp Tôi đã chỉnh sửa câu hỏi của bạn cho rõ ràng vì nhiều DBA mới làm quen sẽ không biết HA hay QO là gì.
Max Vernon

2
Được sử dụng sysindexes.statblobnhưng từ năm 2005 trở về NULLvà vị trí hoàn toàn không có giấy tờ, chỉ có thể truy xuất (mà tôi biết) thông qua DBCC SHOW_STATISTICS(o, i) WITH STATS_STREAM;.
Aaron Bertrand

1
Tìm thấy số liệu thống kê chỉ mục - chúng ở trong sys.sysidxstats- có vẻ như có một con trỏ LOB trong bảng đó. Tôi không chắc chắn số liệu thống kê cột ở đâu; họ có thể ở trong bảng đó cũng như có một typecột.
Jon Seigel

Câu trả lời:


30

Tìm thấy chúng.

  1. Tạo một bảng với một đối tượng thống kê đơn giản.

    CREATE DATABASE splunge;
    GO
    USE splunge;
    GO
    CREATE TABLE dbo.foo(bar INT, munge INT);
    GO
    CREATE STATISTICS x ON dbo.foo(bar);
    CREATE STATISTICS y ON dbo.foo(munge);
    GO
    INSERT dbo.foo SELECT s1.[object_id], s2.[object_id]
      FROM sys.objects AS s1
      CROSS JOIN sys.objects AS s2;
    GO
    UPDATE STATISTICS dbo.foo;
    GO
    
  2. Kết nối bằng cách sử dụng DAC ( ADMIN:Server[\instance]).

  3. Chạy các truy vấn sau:

    DBCC SHOW_STATISTICS('dbo.foo', 'x') WITH STATS_STREAM;
    DBCC SHOW_STATISTICS('dbo.foo', 'y') WITH STATS_STREAM;
    
    SELECT name, imageval 
      FROM sys.stats AS s
      INNER JOIN sys.sysobjvalues AS o
      ON s.object_id = o.objid
      AND s.stats_id = o.subobjid
    WHERE 
      s.object_id = OBJECT_ID('dbo.foo');

Bạn sẽ lưu ý rằng imagevalđối với mỗi đối tượng thống kê không giống với blob thống kê, nhưng nó chứa blob thống kê - nó chỉ là phần bù. Trên hệ thống của tôi, nó mang lại giá trị này cho x (Tôi rõ ràng đã cắt bớt một chút bit):

0x0100...bunch of chars...000007000000C4E1BE00EEA0...rest the same
                            0x07000000C4E1BE00EEA0...rest the same

Và điều này cho y:

0x0100...bunch of chars...430007000000C7E1BE00EEA0...rest the same
                            0x07000000C7E1BE00EEA0...rest the same

Điều này cũng đúng với thống kê dựa trên chỉ số.

Bạn có thể có thể xác nhận thêm về điều này với một loạt các truy vấn bằng cách sử dụng DBCCcác lệnh. Trước tiên, hãy tìm hiểu các trang có liên quan đến chỉ mục được nhóm trên sys.sysobjvalues(thay thế tên cơ sở dữ liệu của bạn):

DBCC IND('splunge', 'sys.sysobjvalues', 1);

Kết quả sẽ liệt kê một loạt các trang, bạn quan tâm đến những trang của PageType = 1. Với cơ sở dữ liệu mới, bạn sẽ có thể tìm thấy thông tin này trên một trong những trang có PagePIDgiá trị cao nhất . Ví dụ, trên hệ thống của tôi, đây là trang 281, vì vậy sau đó tôi nhìn kỹ hơn vào trang đó:

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

DBCC PAGE(@dbid, 1, 281, 3);

DBCC TRACEOFF(3604);

Chắc chắn, tôi tìm thấy dữ liệu trong khe 17:

Kết quả một phần của trang DBCC

(Trên các cơ sở dữ liệu lớn hơn, bạn có thể phải săn lùng và mổ xẻ nhiều hơn, vì không có gì đảm bảo rằng ngay cả một đối tượng thống kê mới sẽ kết thúc trên một trang (er) mới.)

Hãy tiếp tục và thử điều này ở nhà, nhưng có một lý do bạn cần kết nối với DAC cho việc này. Tất nhiên, tôi tò mò muốn biết những gì bạn sẽ làm với thông tin này mà bạn không thể làm với DBCC SHOW_STATISTICSđầu ra.

Lưu ý rằng điều này tất nhiên không cố gắng giải mã STATS_STREAMbiểu đồ để cung cấp biểu đồ hoặc thông tin khác và tôi không thể tìm thấy bất kỳ bằng chứng nào cho thấy đầu ra dạng bảng DBCC SHOW_STATISTICS ... WITH HISTOGRAMđược lưu trữ ở bất cứ đâu trong định dạng bảng. Joe Chang có một số thông tin về giải mã nếu đó là những gì bạn đang theo đuổi. Tôi không nghĩ đó là điều bạn muốn làm trong một truy vấn - chỉ cần sử dụng DBCC.


2
Chúng tôi có một người phụ nữ chiến thắng và quý ông. Tôi ngả mũ của tôi với bạn, thưa ông.
Zane

Hahaha, chúc mừng và cảm ơn, thưa ngài! Đừng lo lắng, tôi không làm bất cứ điều gì tôi không nên (AKA "ngu ngốc"). Nó chỉ dành cho sự phát triển cá nhân. Tôi đã thực sự quan tâm đến nó một khi tôi nhận ra rằng tôi không thể tìm thấy bất cứ điều gì về điều này ở bất cứ đâu. =)
ivanmp

Về bài viết của Joe Chang, tôi đã tìm thấy nó trong khi tôi đang tìm câu trả lời cho điều này. Tôi đã bắt đầu đọc nó. Cảm ơn một lần nữa. :)
ivanmp
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.