页分裂会显著降低索引插入性能,尤其在聚集索引尾部插入不连续键值时最明显;其发生于8KB数据页满载后需插入新记录却空间不足时,引擎将约一半数据移至新页并调整指针,伴随日志写入、锁升级、latch争用及可能的向上分裂。
页分裂会显著降低索引插入性能,尤其在聚集索引的尾部插入不连续键值时最明显。
SQL Server(及其他主流关系型数据库)以固定大小的数据页(通常8KB)为单位存储数据。当一个已满的页需要插入新记录,而该记录无法放入现有空间时,数据库引擎会触发页分裂:将原页约一半数据移到新分配的页中,再调整页间指针(如聚集索引的双向链表或B+树父子节点关系),确保逻辑顺序不变。
这个过程不只是“复制+移动”,还涉及日志写入、锁升级(常升至页面级或更高)、latch争用,以及索引层级可能的向上分裂(如根页或中间页分裂),带来明显开销。
主键插入:如使用NEWID()生成的GUID作为聚集索引键,新行几乎总需插入到中间位置,导致频繁分裂可通过系统视图查看页级碎片和分裂统计:
-- 查看索引碎片率(重点关注avg_page_space_used_in_percent 和 page_count)
SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('Orders'), NULL, NULL, 'DETAILED');
-- 查询页分裂等待(间接指标)
SELECT * FROM sys.dm_os_wait_stats WHERE wait_type IN ('PAGEIOLATCH_UP', 'PAGELATCH_EX');
持续出现高PAGELATCH_EX等待(尤其是集中在聚集索引页),配合高平均碎片率(>30%)和低页空间使用率(