表无索引为什么sp_spaceused 中的index_size不为0
2009-10-18 22:23
295 查看
源于csdn论坛的一个提问:
CREATE TABLE TUser ( FName CHAR(8000), FAge INT, FSex bit )
INSERT INTO TUser
SELECT '张三',18,1 UNION ALL
SELECT '李四',20,1 UNION ALL
SELECT '王五',32,1 UNION ALL
SELECT '麻子',23,1
通过一个查询看下扫描的数据页:
SET STATISTICS IO ON
SELECT * FROM TUser
EXEC sp_spaceused N'TUser'
sp_helptext sp_spaceused
通过查看sp_spaceused的代码,我们找到对于我们这个查询有用的信息代码:
SELECT
@reservedpages = SUM (reserved_page_count),
@usedpages = SUM (used_page_count),
@pages = SUM (
CASE
WHEN (index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
ELSE lob_used_page_count + row_overflow_used_page_count
END
),
@rowCount = SUM (
CASE
WHEN (index_id < 2) THEN row_count
ELSE 0
END
)
FROM sys.dm_db_partition_stats
WHERE object_id = @id;
IF (SELECT count(*) FROM sys.internal_tables WHERE parent_id = @id AND internal_type IN (202,204)) > 0
BEGIN
SELECT
@reservedpages = @reservedpages + sum(reserved_page_count),
@usedpages = @usedpages + sum(used_page_count)
FROM sys.dm_db_partition_stats p, sys.internal_tables it
WHERE it.parent_id = @id AND it.internal_type IN (202,204) AND p.object_id = it.object_id;
END
SELECT
name = OBJECT_NAME (@id),
rows = convert (char(11), @rowCount),
reserved = LTRIM (STR (@reservedpages * 8, 15, 0) + ' KB'),
data = LTRIM (STR (@pages * 8, 15, 0) + ' KB'),
index_size = LTRIM (STR ((CASE WHEN @usedpages > @pages THEN (@usedpages - @pages) ELSE 0 END) * 8, 15, 0) + ' KB'),
unused = LTRIM (STR ((CASE WHEN @reservedpages > @usedpages THEN (@reservedpages - @usedpages) ELSE 0 END) * 8, 15, 0) + ' KB')
通过上面的代码,我们可以基于我们目前的这个情况(堆表,不含有xml和fulltext,所以上面的202/204那段不用管了)提练出index的page如下算法:
select index_pagecount=sum(used_page_count)-
sum(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
from sys.dm_db_partition_stats
where object_id = object_id('TUser');
这个结果是1.再套上index_size的公式:
select index_size = LTRIM (STR ((1) * 8, 15, 0) + ' KB')
/**//*
8k
*/
这就是8k的算法,从下面联机文档上关于sys.dm_db_partition_stats 的解释,可以分析出这个8k是个IAM page.
used_page_count bigint
用于分区的总页数。计算方法为 in_row_used_page_count + lob_used_page_count + row_overflow_used_page_count
上面我们算index_page时公式为:
sum(used_page_count)-
sum(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
也就是in_row_used_page_count -in_row_data_page_count
对于这两列,联机文档解释是:
in_row_used_page_count
用于存储和管理分区中的行内数据的总页数。该计数包括非叶 B 树页、IAM 页以及 in_row_data_page_count 列包含的全部页。
in_row_data_page_count
分区中存储行内数据所用的页数。如果分区是堆的一部分,则该值为堆中的数据页数。如果分区是索引的一部分,则该值为叶级别中的页数。(未计入 B 树中非叶页的数目。)以上两种情况都未计入 IAM(索引分配映射)页。
针对我们目前该表的情况,仅是一个堆表,那么可知前者是包含了IAM页,而后者不含有IAM页,那么sp_spaceused中的index_size在这里就是一个IAM(索引分配映射)页。
其实这个也可以通过DBCC IND看到:
如有错误,欢迎指正。
CREATE TABLE TUser ( FName CHAR(8000), FAge INT, FSex bit )
INSERT INTO TUser
SELECT '张三',18,1 UNION ALL
SELECT '李四',20,1 UNION ALL
SELECT '王五',32,1 UNION ALL
SELECT '麻子',23,1
通过一个查询看下扫描的数据页:
SET STATISTICS IO ON
SELECT * FROM TUser
EXEC sp_spaceused N'TUser'
sp_helptext sp_spaceused
通过查看sp_spaceused的代码,我们找到对于我们这个查询有用的信息代码:
SELECT
@reservedpages = SUM (reserved_page_count),
@usedpages = SUM (used_page_count),
@pages = SUM (
CASE
WHEN (index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
ELSE lob_used_page_count + row_overflow_used_page_count
END
),
@rowCount = SUM (
CASE
WHEN (index_id < 2) THEN row_count
ELSE 0
END
)
FROM sys.dm_db_partition_stats
WHERE object_id = @id;
IF (SELECT count(*) FROM sys.internal_tables WHERE parent_id = @id AND internal_type IN (202,204)) > 0
BEGIN
SELECT
@reservedpages = @reservedpages + sum(reserved_page_count),
@usedpages = @usedpages + sum(used_page_count)
FROM sys.dm_db_partition_stats p, sys.internal_tables it
WHERE it.parent_id = @id AND it.internal_type IN (202,204) AND p.object_id = it.object_id;
END
SELECT
name = OBJECT_NAME (@id),
rows = convert (char(11), @rowCount),
reserved = LTRIM (STR (@reservedpages * 8, 15, 0) + ' KB'),
data = LTRIM (STR (@pages * 8, 15, 0) + ' KB'),
index_size = LTRIM (STR ((CASE WHEN @usedpages > @pages THEN (@usedpages - @pages) ELSE 0 END) * 8, 15, 0) + ' KB'),
unused = LTRIM (STR ((CASE WHEN @reservedpages > @usedpages THEN (@reservedpages - @usedpages) ELSE 0 END) * 8, 15, 0) + ' KB')
通过上面的代码,我们可以基于我们目前的这个情况(堆表,不含有xml和fulltext,所以上面的202/204那段不用管了)提练出index的page如下算法:
select index_pagecount=sum(used_page_count)-
sum(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
from sys.dm_db_partition_stats
where object_id = object_id('TUser');
这个结果是1.再套上index_size的公式:
select index_size = LTRIM (STR ((1) * 8, 15, 0) + ' KB')
/**//*
8k
*/
这就是8k的算法,从下面联机文档上关于sys.dm_db_partition_stats 的解释,可以分析出这个8k是个IAM page.
used_page_count bigint
用于分区的总页数。计算方法为 in_row_used_page_count + lob_used_page_count + row_overflow_used_page_count
上面我们算index_page时公式为:
sum(used_page_count)-
sum(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
也就是in_row_used_page_count -in_row_data_page_count
对于这两列,联机文档解释是:
in_row_used_page_count
用于存储和管理分区中的行内数据的总页数。该计数包括非叶 B 树页、IAM 页以及 in_row_data_page_count 列包含的全部页。
in_row_data_page_count
分区中存储行内数据所用的页数。如果分区是堆的一部分,则该值为堆中的数据页数。如果分区是索引的一部分,则该值为叶级别中的页数。(未计入 B 树中非叶页的数目。)以上两种情况都未计入 IAM(索引分配映射)页。
针对我们目前该表的情况,仅是一个堆表,那么可知前者是包含了IAM页,而后者不含有IAM页,那么sp_spaceused中的index_size在这里就是一个IAM(索引分配映射)页。
其实这个也可以通过DBCC IND看到:
如有错误,欢迎指正。
相关文章推荐
- 分析表无索引为什么sp_spaceused 中的index_size不为0
- 关于重新组织和重新生成索引sp_RefreshIndex的介绍
- SQL2012 重新组织和新生成索引sp_RefreshIndex
- Oracle中的index学习 ---理解索引为何物,为什么会使查询变快
- 关于重新组织和重新生成索引sp_RefreshIndex的介绍
- 重新生成索引存储过程 sp_rebuild_index
- How to reduce Index size on disk?减少ES索引大小的一些小手段
- 扩展 sp_helpindex, 增加 INCLUDE 和筛选索引的筛选条件
- 空间索引网格大小无效的解决方法The spatial index grid size is invalid
- 为什么通过sp & ~(THREAD_SIZE - 1) 可以获取到 task_struct
- 空间索引网格大小无效的解决方法The spatial index grid size is invalid
- 倒排文件索引(Inverted File Index)的建立
- Oracle index】SQL语句利用函数索引注意点
- 谈谈深度学习中的 Batch_Size Batch_Size(批尺寸)是机器学习中一个重要参数,涉及诸多矛盾,下面逐一展开。 首先,为什么需要有 Batch_Size 这个参数? Batch 的选
- GridView1.DataKeys[e.RowIndex].Value.ToString() 索引超出范围问题
- 为何要重建索引 index
- 关于分区技术的索引 index
- Mysql——index(索引)使用
- SQLServer查看数据表占用硬盘的空间大小:sp_spaceused
- The spatial index grid size is invalid 问题解决