关于数据库锁的猜想
page1 | page2 | page3 |
page4 | page5 | page6 |
page7 | page8 | page9 |
row1 |
row2 |
row3 |
row4 |
row5 |
数据库锁的粒度大体分为:库级锁,表级锁,页级锁,行级锁
如果一个表的数据分散在9个页上,每个页上有5行数据,
如果有10行要更新的数据分布在page1,page2,page6上,
那么如果用锁模式为页锁,则需要3把页锁,用行锁需要10把行锁,用表锁只需要一把。
当只更新一行的时候,实际上最少只需要一把行锁,如果用页锁,
则被所住页的其他4行其实是不需要锁的,如果被锁了,当并发高的时候,恰逢这4行数据需要锁,但是已经被页锁锁住,则降低了并发性。
当要更新45行的时候,实际上最少只需要一把表锁,如果用页锁,
则需要5把页锁,若用行锁,则需要45把!也就是增加了维护锁的开销。
这里就有一个平衡,并发高(→row)则锁开销高,并发低(→table)则锁开销小。
猜想一下事务。
===开启事务===
被更新表共有n行
更新10%行数据(行锁0.1n把/表锁1把/页锁若干)
如果用行锁,当n很大的时候,那就产生0.1n的行锁,n=100万,就要10万把行锁,开销大吗?
===提交事务===
如果这个更新慢了,可能就是因为锁开销太大了。但是带来的好处是,我更新这10万行数据的时候,并不锁其他90万行的数据。
所以,如果猜想成立,建议对会涉及很多数据的更新语句,先考察一下数据分布,再用适合的锁模式。
近日发现,好像数据库有锁的阀值,如果数据库锁阀值为500,一个事务中行锁的数量超过500,则会自动提升为页锁,
只是听说,未见详细理论。