为什么索引扫描读取的页面比索引中存在的页面多?

Rad*_*hiu 3 sql-server sql-server-2008-r2

我一直在尝试为一个测试场景运行一些查询,我注意到在对非聚集索引进行全面扫描时,SQL Server 读取的页面比索引中的实际页面多。

从下图可以看出,我的查询是(一个简单的):

select
    sometext
    , somemoretext
from tbl
Run Code Online (Sandbox Code Playgroud)

我有这些列的精确覆盖非聚集索引。

在此处输入图片说明

在 Profiler 中,为此读取的页数22,356如您在图像中所见。

但是查看索引详情的时候,在Fragmentation下,这个索引的页数是22,278

在此处输入图片说明

读取页面差异的原因是什么(78准确地说)?Fragmentation 部分中的数字是不可靠的还是有其他解释?

索引没有碎片(或似乎没有),所以没有比那些更多的页面了22,278……或者有吗?我无法在网上、微软网站或其他网站上找到对此的解释。

(这是一个受控环境,在为这个问题截屏时,表上没有发生插入和删除)

我也把计划贴在这里

sep*_*pic 9

当您打开“Fragmentation”(使用SQL Server Profiler)时,您应该检查哪些代码提交给服务器

你会看到以下代码:

select partition_number as PartitionNumber,
       index_type_desc  as IndexType,
       index_depth as Depth,
       avg_fragmentation_in_percent as AverageFragmentation,
       page_count   as Pages,
       avg_page_space_used_in_percent   as AveragePageDensity,
       record_count as Rows,
       ghost_record_count   as GhostRows,
       version_ghost_record_count   as VersionGhostRows,
       min_record_size_in_bytes as MinimumRecordSize,
       max_record_size_in_bytes as MaximumRecordSize,
       avg_record_size_in_bytes as AverageRecordSize,
       forwarded_record_count as ForwardedRecords 
from sys.dm_db_index_physical_stats(7, 773577794, 2, NULL, 'SAMPLED')
Run Code Online (Sandbox Code Playgroud)

注意模式:它是'SAMPLED'.

该代码只返回1行反映page_countleaf level索引。

现在更改要使用的代码'DETAILED',您将在非叶级别找到丢失的页面。

这是我的再现。

我首先查看 Fragmentation 选项卡,我发现我的ix_include_filler索引有20836页面。

然后我执行了我在 中看到Profiler的代码,并且使用的代码"SAMPLED"返回 1 行并显示20836我们在"Fragmentation"选项卡中看到的页面。

然后,我改变"SAMPLED""DETAILED"和清楚地看到,这些20836仅仅是从一个叶级。N1 级有其他36页面 + 一个根。

如果您SSMS在打开 Fragmentation 选项卡时启动不同的代码,也许您应该使用 SSMS 版本更新您的问题并监视它自己发送的代码。

我的 SSMS 的版本是10.50.6000.34,我的解释对这个版本有效。

在此处输入图片说明