目录


  • 目录
  • 简述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的from dual 用法_表的类型

SQL Server是通过分区去管理与组织数据记录的,且每个表至少存在一个分区,每个分区可对应一个文件组(系统默认文件组为PRIMARY)。换言之,可认为表的默认分区为PRIMARY。

聚集索引表与堆表的最大区别是:聚集索引表的数据在组织上是有序的,即聚集索引的有序性。而堆表是不含聚集索引的表。

注意:上述的组织结构是表或索引的存储结构。在SQL Server现有的版本中,还无法对表的单个分区建立索引(聚集或非聚集索引都不行)

简而言之,目录视图sys.partitions与sys.indexes均存有索引的相关信息,因此这两个视图查询聚集索引的信息,然后就可区分表的类型。

聚集索引表与堆表的正确使用

我们有很多理由去创建一个聚集索引表,而非堆表。那么最大的理由可能就是:当一个非聚集索引包含的列不能完全符合一条查询(select)时,执行计划可通过聚集索引查找,而非通过表扫描的方式。

那么我们为什么会选择堆表,原因大致就如下2点:
1. 堆表没有聚集索引,因此堆表可节省索引的磁盘空间
2. 堆表没有聚集索引,且数据组织是无序的,节省了排序操作,写入操作更快。