SQLSERVER解决HOT PAGE问题的其中一个思路使用表分区
什么叫HOT PAGE?
应用程序发来大量的并发语句在修改或者插入同一张表格里的记录,而表格架构设计以及用户业务逻辑使得这些修改跟插入都集中在同一个数据页面,
或者数量不多的几个数据页面上。这些页面有时候也被称为 hot page 热点页。这样的瓶颈通常只会发生在并发用户比较多的、典型的OLTP系统上。
介绍一下PAGELATCH:
简单来讲,当SQLSERVER把数据读取到内存之后,数据以“页”为单位存放的,假如有两个用户同时修改或者插入的数据都在同一个页面,那么,
SQLSERVER会在页面上放一个PAGELATCH(轻量级的)锁,这些锁跟意向共享锁、排他锁、行锁、键锁不同,这些LATCH锁只存在于内存里
当A用户要修改数据页编号为100这个页面时,SQLSERVER就会在100这个页面加上一个PAGELATCH锁,以防止其他用户同时修改这个页面
以得到一个修改的先后顺序,当A用户修改完毕以后,PAGELATCH就会释放,以供B用户修改。
一般使用下面的SQL语句的wait_type列就可以看到当前哪个会话需要等待获得PAGELATCH锁
1 SELECT * FROM sys.[dm_exec_requests]
HOTPAGE介绍完了,PAGELATCH介绍完了,那么这个HOTPAGE带来的瓶颈以及危害大家应该知道了吧?
不知道?好吧,跟大家说一下:
如果大量并发用户同时访问同一个数据页面,那么SQLSERVER就要对这个数据页面的PAGELATCH进行申请释放,
不断申请和释放,如果SQLSERVER处理用户的插入或者修改请求比较慢的话,那么就会造成“阻塞”。
一般HOTPAGE会在以下情况发生:
例如:有一个股票交易系统,每一笔交易都会有一个流水号是递增而且不可重复的而客户发过来的交易请求,
都要存储在同一张交易表里。每一个新的交易,都要插入一条新记录。如果设计者选择在流水号上建聚集索引(这也是很自然的)
就容易遇到HOT PAGE的PAGE LATCH资源瓶颈。在同一时间,只能有一个用户插入一笔交易
怎样才能缓解这种瓶颈呢?
(1)最简单的方法:换一个数据列建聚集索引,而不要建立在IDENTITY字段(例如上面的交易流水号)上。
这样表格里的数据就按照其他方式排序,同一时间的插入就有机会分散在不同的页面上
(2)如果实在是一定要在IDENTITY的字段上建立聚集索引,建议根据其他某个数据列在表格上建立若干个分区(Partition)表分区,
把一个表格分成若干个分区,可以使得接受新数据的页面数目增加
例如:
以上面的那个股票交易系统为例子。不同的股票属于不同的行业。开发者可以根据股票的行业属性,将一张交易表分成若干个分区。
在SQLSERVER里,已分区表(Partition Table) 的每个分区都是一个独立的存储单位。分属不同分区的数据行是严格分开存储的。
所以,同一个时间发生的交易记录,因其他行业不同,也会分别保存在不同的分区里。这样,在同一个时间点,可以插入不同行业的
交易记录。每个分区上的HOT PAGE(接受新数据插入的PAGE)就不那么HOT了
所以,在自增列上建立聚集索引要看情况,不然会很容易遇到HOTPAGE噢 o(∩_∩)o
2012-12-27补充
在这里再说一下,分区是把双刃剑,如果分区了的话,会带来扫描次数的增多
原本表没有分区的,那么扫描一次就可以了,现在比如分了2个区,那么就要
扫描2次,每个分区需要2次I/O,那么如果数据在分区2里面的话,就需要
4次I/O
这种情况只是latch争用情况的一种