在 SQL Server 中的表上没有聚集索引有什么好处?
将要:
SELECT * INTO TABLE_A FROM TABLE_B
TABLE_A
如果是堆,会更快吗?
如果表是堆,哪些操作将受益?
我很确定UPDATE
s 和DELETE
s 将从聚集索引中受益。s呢INSERT
?我的理解是,INSERT
“可能”受益于作为堆的表,无论是在速度方面,还是在其他资源和硬件(I/O、CPU、内存和存储......)方面。
就硬件而言,最稀缺的资源是什么?在存储方面,堆会占用更少的空间吗?磁盘存储不是最便宜的资源吗?如果是这样,将表保留为堆以节省磁盘空间是否合理?SELECT
使用、和INSERT
,堆将如何影响 CPU 和 I/O ?当 table 是一个 heap 和 we 时,成本会增加多少?UPDATE
DELETE
SELECT
UPDATE
DELETE
我只是在解决标题中的问题。问题主体有太多不同的问题需要在堆栈交换答案中回答。与具有聚集索引的表相比,堆具有以下优点:
具有聚集索引的表按这些索引的顺序物理组织数据。如果要插入的数据尚未按聚集键顺序排序,SQL Server 查询优化器可能会向查询计划添加足够大的插入排序。排序执行的额外工作不是免费的,因此查询可能会运行得更慢。插入非分区堆不需要排序的源数据。
最小日志记录规则在堆和聚集索引之间的工作方式不同。在某些情况下,插入到堆中将写入事务日志的字节数少于插入到具有聚集索引的表中的可比较的字节。有关一些示例,请参阅数据加载性能指南。
聚集索引可防止并行插入到表中。查询计划的插入部分将始终位于串行区域 (DOP = 1)。从 SQL Server 2016 开始,在没有非聚集索引的堆中插入可以符合并行插入的条件。
当许多单独的进程插入同一个表时,聚集索引将增加锁和闩锁争用。没有非聚集索引的堆可以由多个进程同时加载,并且争用较少,尤其是当这些插入来自 SQL Server 之外并具有批量更新锁时。
在非持久内存优化表之后,堆是加载和读取成本第二低的表设计。所以它非常适合用作临时表。
对于非常大的表,聚集列存储比堆好得多。加载更昂贵(特别是如果您不批量加载),但它更节省空间,并且阅读速度要快得多。
除此之外,您的表通常应该有一个聚集的主键。