SQL Server 中的统计信息物理存储在哪里?

iva*_*nmp 28 sql-server statistics database-internals

查询优化器使用的统计信息物理存储在 SQL Server 数据库文件和缓冲池中的什么位置?

更具体地说,有没有办法使用 DMV 和/或 DBCC 找出统计数据使用的页面?

我拥有 SQL Server 2008 Internals 和 SQL Server Internals and Troubleshooting 书籍,但没有一本涉及统计的物理结构;如果他们这样做,我将无法找到此信息。

Aar*_*and 31

找到他们。

  1. 使用简单的 stats 对象创建一个表。

    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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用 DAC ( ADMIN:Server[\instance]) 进行连接。

  3. 运行以下查询:

    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');
    
    Run Code Online (Sandbox Code Playgroud)

您会注意到,imageval对于每个 stats 对象与 stats blob 不同,但它确实包含stats blob - 它只是偏移量。在我的系统上,它为 x 产生了这个(我显然已经截断了相当多的位):

0x0100...bunch of chars...000007000000C4E1BE00EEA0...rest the same
                            0x07000000C4E1BE00EEA0...rest the same
Run Code Online (Sandbox Code Playgroud)

这对于 y:

0x0100...bunch of chars...430007000000C7E1BE00EEA0...rest the same
                            0x07000000C7E1BE00EEA0...rest the same
Run Code Online (Sandbox Code Playgroud)

基于索引的统计也是如此。

您可能可以通过一系列使用DBCC命令的查询对此进行进一步验证。首先,找出与聚集索引相关的页面sys.sysobjvalues(替换您的数据库名称):

DBCC IND('splunge', 'sys.sysobjvalues', 1);
Run Code Online (Sandbox Code Playgroud)

结果将列出一堆页面,您对PageType = 1. 使用新数据库,您应该能够在具有最高PagePID值的页面之一上找到此信息。例如,在我的系统上,这是第 281 页,所以我仔细查看了该页面:

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

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

DBCC TRACEOFF(3604);
Run Code Online (Sandbox Code Playgroud)

果然,我在slot 17找到了数据:

DBCC页面的部分结果

(在较大的数据库上,您可能需要进行更多的搜索和啄食,因为无法保证即使是新的 stats 对象也会出现在新的(er)页面上。)

继续在家中尝试此操作,但您需要为此与 DAC 连接是有原因的。当然,我很想知道您将如何处理这些无法使用DBCC SHOW_STATISTICS输出的信息。

请注意,这当然不会尝试解码STATS_STREAM以提供直方图或其他信息,而且我找不到任何证据表明 的表格输出DBCC SHOW_STATISTICS ... WITH HISTOGRAM以表格格式存储在任何地方。Joe Chang 有一些关于解码的信息,如果这是你所追求的。我不认为这是您想在查询中执行的操作 - 只需使用DBCC.

  • 我们有一位获胜者女士们先生们。先生,我向您致敬。 (2认同)