insert rows into heap/clustered table

 

Insert row to a heap.

IAM包含一个对象所占用所有空间(extent), PFS包含了所有数据页的空间使用情况的信息。

当向堆(heap)插入一条记录时, sqlserver会检测这个对象的IAM页和PFS页(加上S LATCH),判断是否和可用的数据页,如果有,则向相应的数据页插入数据,如果插入的数据量达到了PFS的阀值,会更新PFS页内的信息(需要U LATCH)

如果没有可用的数据页,则会

如果当前页的数量>8,检测GAM页(加上S LATCH),查看时候有可用的Extent,如果没有,则检测下一个GAM...如果找到可用的extent,则更新相应的GAM,IAM,PFS(需要U LATCH) 

如果当前页的数量<8检测SGAM页(加上S LATCH),查看时候有可用的Extent,如果没有,则检测下一个SGAM...如果找到可用的extent,则更新相应的SGAM,IAM,PFS(需要U LATCH)

 

如果对数据有delete,update操作,导致数据页空间上的变化,也要更新PFS,也可能更新相应的GAM,SGAM,IAM,这都需要u latch.    可以想象的出,在高并发所以如果在高频发的情况下, 会出现这些分配页上的热点,形成瓶颈(假设其它的资源不是瓶颈)

 

接下来看看clustered table的情况。

Insert row to a clustered index table

假设clustered key符合unique,narrow,static ,ever-increasing原则。

插入的过程和index seek的过程有些类似, 首先通过root page intermate page定位新的行应该插入的位置,这样就定位到了行所在的数据页,然后完成插入操作。

在定位的阶段中,会对root pageintermate leve pages进行锁定(S LATCH), 如果插入的数据量非常大,导致了root pageintermate level pages中的某个页发生了变化,也会对root page和相应的intermate level page进行锁定(U LATCH),对于小数据量的表来说,可能插入了若干行数据后,intermate level pages就需要更新了,再插入更多的数据后,root page也要进行更新。但对于一个大数据量的表来说,这种情况发生的频率会更低。

 

在实际插入的时候,会对影响的data page进行锁定(U LATCH),完成后更新相应的IAM,GAM页(如果需要申请新的EXTENT)。假设I/O,CPU都不是问题的情况下,这些页就可能成为频繁插入的瓶颈了。目前SQL SERVER并没有内置的解决方案,不过可以考虑使用PARTITION来解决。

 

参考

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/07/08/under-the-covers-gam-sgam-and-pfs-pages.aspx

http://msdn.microsoft.com/en-us/library/ms187501.aspx

 http://social.msdn.microsoft.com/Forums/zh-CN/sqlserverzhchs/thread/2a284381-c5d2-4e52-aac6-da616b042fb5/#52e00c9e-50b3-476c-9f15-64e6c8e5b722

 

http://sqlblog.com/blogs/linchi_shea/archive/2007/01/22/hash-partition-as-a-design-method.aspx

http://sqlcat.com/technicalnotes/archive/2009/09/22/resolving-pagelatch-contention-on-highly-concurrent-insert-workloads-part-1.aspx


 

原文地址:https://www.cnblogs.com/stswordman/p/1917018.html