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 page和intermate leve pages进行锁定(S LATCH), 如果插入的数据量非常大,导致了root page和intermate 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://msdn.microsoft.com/en-us/library/ms187501.aspx
http://sqlblog.com/blogs/linchi_shea/archive/2007/01/22/hash-partition-as-a-design-method.aspx