查询优化器使用的统计信息实际存储在SQL Server数据库文件和缓冲池中的什么地方?

更具体地讲,有没有办法找出使用DMV和/或统计信息使用的页面? DBCC?我同时拥有SQL Server 2008内部和SQL Server内部和疑难解答书籍,但它们都没有谈到统计信息的物理结构。如果没有,我将找不到此信息。

评论

当您创建仅统计信息的数据库副本时,它会显示二进制STATS_STREAM,我从没研究过它是否可以在文件本身中找到。

统计信息由仅内部聚合函数(StatMan)创建,该函数输出一个Blob(具有讽刺意味的是,该名称在SSMS查询窗口中突出显示为函数)。从逻辑上讲,统计信息与索引或一组表列相关联,因此,我将从检查内部元数据表开始,以查找将导致该Blob的二进制或varbinary列。应该可以使用DBCC PAGE看到它,但是可能不是任何其他方式,因为它们都是内部的。

@ivanmp我为清楚起见编辑了您的问题,因为许多新手DBA都不知道BP或QO是什么。

曾经在sysindexes.statblob中,但是从2005年开始,它返回NULL,并且该位置完全未记录,只能通过DBCC SHOW_STATISTICS(o,i)WITH STATS_STREAM;检索(据我所知)。

找到索引统计信息-它们位于sys.sysidxstats中-看起来该表中有一个LOB指针。我不确定该列的统计信息在哪里;它们可以在该表中,也可以有一个类型列。

#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


使用DAC连接( ADMIN:Server[\instance])。

运行以下查询:

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');



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

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


对于y:

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


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

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

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


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

DBCC TRACEON(3604);

DECLARE @dbid INT = DB_ID();

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

DBCC TRACEOFF(3604);


果然,我在插槽17中找到了数据:



(在较大的数据库上,您可能不得不做更多的工作,因为无法保证即使是新的stats对象也将最终出现在新的页面上。 )

继续在家里尝试一下,但是有一个原因需要为此与DAC连接。我很想知道,当然,您将使用DBCC SHOW_STATISTICS输出无法处理的此信息。

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

评论


我们有一位得奖的女士们先生们。先生,我给你戴帽子。

–赞恩
2012年10月18日16:09

哈哈哈,恭喜,先生!不用担心,我没有做任何我不应该做的事情(又称“愚蠢”)。这只是为了个人成长。当我意识到自己在任何地方都找不到任何东西时,我对此变得非常感兴趣。 =)

– ivanmp
2012年10月18日16:11

关于Joe Chang的文章,我在寻找答案的同时发现了。我已经开始阅读它。再次感谢。 :)

– ivanmp
2012年10月18日在16:14