目录
- 目录
- 简述SQL Server表的类型
- 如何区分聚集索引表与堆表
- 聚集索引表与堆表的正确使用
- 参考资料
简述SQL Server表的类型
由于当前关系型数据库(RDBMS)种类繁多,存在对标准SQL(结构化查询语言)实现上存在差异,对表、索引的实现也各有不同,造成了大家对很多概念在理解上存在误差。如下将描述MS SQL Server的聚集索引表与堆表,以便大家重新理解。
SQL Server只存在2种表:
聚集索引表(Clustered table)
堆表(Heap)
简单的说,含有聚集索引(clustered index)的表即为聚集索引表,而堆表则是不含聚集索引的表。
注意:仅含有非聚集索引(Nonclustered index),而没有聚集索引(clustered index)的表是堆表
如何区分聚集索引表与堆表
通过目录视图(catalog views)sys.partitions或sys.indexes可查询表的类型:
--通过判断index_id的值,区分表的类型
--当index_id为0时,则为堆表
--当index_id为1时,则为聚集索引表
SELECT
OBJECT_NAME(s.object_id) talbe_name
,CASE s.index_id
WHEN 0 THEN 'heap'
WHEN 1 THEN 'clustered table'
END table_type
FROM sys.partitions s
WHERE s.index_id < 2
GROUP BY s.object_id,s.index_id
使用目录视图sys.indexes查询表的类型:
--注意:当表为堆表时,name为NULL
SELECT
OBJECT_NAME(object_id) table_name,
name,
type_desc
FROM sys.indexes
WHERE index_id <2
注意:上述sql适用于所有的表。换言之,分区表也可使用上述sql进行判断。
你可能好奇为何上述2个目录视图(sys.partitions或sys.indexes)可查询所有表的类型(聚集索引表或堆表),那么我们需简单描述表与索引的组织结构,见下图(图片取自《Microsoft SQL Server 2008 Internals》)
SQL Server是通过分区去管理与组织数据记录的,且每个表至少存在一个分区,每个分区可对应一个文件组(系统默认文件组为PRIMARY)。换言之,可认为表的默认分区为PRIMARY。
聚集索引表与堆表的最大区别是:聚集索引表的数据在组织上是有序的,即聚集索引的有序性。而堆表是不含聚集索引的表。
注意:上述的组织结构是表或索引的存储结构。在SQL Server现有的版本中,还无法对表的单个分区建立索引(聚集或非聚集索引都不行)
简而言之,目录视图sys.partitions与sys.indexes均存有索引的相关信息,因此这两个视图查询聚集索引的信息,然后就可区分表的类型。
聚集索引表与堆表的正确使用
我们有很多理由去创建一个聚集索引表,而非堆表。那么最大的理由可能就是:当一个非聚集索引包含的列不能完全符合一条查询(select)时,执行计划可通过聚集索引查找,而非通过表扫描的方式。
那么我们为什么会选择堆表,原因大致就如下2点:
1. 堆表没有聚集索引,因此堆表可节省索引的磁盘空间
2. 堆表没有聚集索引,且数据组织是无序的,节省了排序操作,写入操作更快。