SQL Passion Week 5: 堆表
今天我们介绍下所谓的堆表(Heap table), 堆表就是没有聚集索引的表. 在SQL Server中,一个表如果包含聚集索引, 我们就称为索引表, 否则就称为堆表.
在堆表中, 数据是无序的, 它们只是杂乱的放在一起, 没有结构性. 当我们select一个堆表时, 如果没有合适的非聚集索引, SQL Server会使用表扫描(Table Scan)操作来检索数据, 而不是表查找(Table Seek).
表扫描意味着将扫描整个表, 数据越多, 耗费的时间越久.
我们来看一下堆表的优点和缺点.
优点
堆表的insert操作非常非常快, 因为它是无序的, 别无其他. 在插入数据时, 无需比较已有的数据, 分配一个新的地址, 写入新纪录, 就完事了.
因为这个原因, 我们可以将一些需要频繁,并行insert动作的表作为堆表来处理. 比如日志表. 除此之外,我们不推荐在任何地方使用堆表.
缺点
第一个缺点, 堆表在读取过程中导致了存储系统的随机IO. 想象一下你对一个堆表执行select语句, 如果数据当前没有cache在buffer pool里, SQL Server必须到存储系统中去物理读数据. 因为堆表的存储是随机散步在数据文件中, 而不是连续的. 这就造成了random I/O. 大家都知道, 我们目前普遍使用的是物理磁盘, 随机IO非常非常的慢.
如果是SSD固态硬盘的话, 随机IO和顺序IO就没太大的区别了,虽然前者依然慢了一点点.
另外一个问题就是堆表会产生Forwarding Records. 当某个页上存储的数据更新超过长度时, SQL Server会留下一个指针,指向一个新的存储位置. 这使得在检索数据时会严重的影响性能. 我们在这里留个坑, 就不具体讨论Forwarding Records深层次的问题了,有兴趣可以自行搜索下相关文档.