我的一个客户有一个基于预订的系统。与航线类似。在MS SQL 2005上运行。
上一家公司设计的方式是将分配创建为一组行。
简单示例:
AllocationId | SeatNumber | IsSold
1234 | A01 | 0
1234 | A02 | 0
在出售座位的过程中,系统会在桌面上建立更新锁定。
我们遇到的问题是锁定过程运行缓慢,我们正在寻找加快速度的方法。
该表已经有效地建立索引,因此我们正在寻找一种加速该过程的硬件解决方案。该表大约有5 mil活动行,位于RAID 50 SAS阵列上。
我假设硬盘搜索时间将是加速更新锁的限制因素,当你有5行的行并且一次更新2-5行时(我可能是错的)。
关于在多个磁盘阵列上使用索引分区的人们,我是否曾尝试加速锁定?任何人都可以给我一些建议,找出可能升级的硬件或我们可以利用什么技术来加速更新锁(不移动到集群)的可能解决方案?
答案 0 :(得分:0)
我认为你没有从表分区中得到任何东西 - 你得到的唯一改进是从较小(较短)的索引树中读取较少的磁盘(每次读取都会达到索引的每个级别)至少一次,所以读取的速度越快,越少。)但是,我有一个带有4M +行分区的表,索引为4列,净10字节密钥长度。它符合三个指数水平,最高水平为42.6%。假设你有类似的东西,分区可能只从树中移除一个级别似乎是合理的,我怀疑这是一个很大的改进。
一些袖手旁观的想法:
由于奇偶校验计算,Raid 5(和50)在写入时可能会变慢。如果磁盘I / O缓存足够大以处理工作负载,那么问题就不是问题(或者说我已经说过了),但是如果这种问题充满了你可能会想看看raid 10。
将表分区到多个驱动器阵列。使用两个(或更多)Raid阵列,将表分布在卷[文件/文件组,有或没有表分区或分区视图]上,并且您有两倍的磁盘I / O速度,具体取决于数据所在的位置相对于检索它的查询。 (如果阵列#1和阵列#2上的每一个都是空闲的,那么你什么也得不到。)
最糟糕的情况是,可能会出现前沿或尖端技术,这会让你的袜子脱落。如果它对您的业务至关重要并且您已经获得了预算,那么可能值得进行一些认真的研究。
答案 1 :(得分:0)
长如何更新锁等待?
为什么“表格”上的锁定不仅仅是“行”的销售?
如果锁定保持的次数超过a 可能的第二个派系 是你的问题。 SqlServer没有 就像你在用户时持有锁 填写网页表格等。
使用SqlServer,您必须自己实施“购物车”,暂时保留座位,直到用户付费为止。例如,添加“IsReserved”和“ReservedAt”colunn,那么任何已保留超过n分钟的座位应自动保留。
这是一个难题,因为购物者不希望有库存的座位出售给他正在结账的其他人。但是,您不知道购物者是否会完成结账。那么如何在UI上显示它呢?考虑看看其他预订网站的内容,然后复制一个用户已经知道如何使用的网站。
(甲骨文有时可以应对长时间保存的锁定,但如果你保持锁定时间短,那么即使是Oracle也会更快更快乐。“
答案 2 :(得分:0)
我首先想弄清楚你为什么要锁定表而不是一行。 要检查的一件事是Update语句的执行计划,以查看它导致更新的索引,然后确保在这些索引上启用了row_level_lock和page_level_lock。 您可以使用以下语句执行此操作。
Select allow_row_locks, allow_page_locks from sys.indexes where name = 'IndexNameHere'
答案 3 :(得分:0)
最后一次尝试......
很明显,持有的锁太多了。
一旦系统开始减速 由于锁太多,没有 指出开始更多交易。
因此,您应该对系统进行基准测试以找出最佳数量的葡萄干交易,然后使用一些队列系统(或其他方式)来限制葡萄干交易的数量。 Sql Server可能有一些设置(活动连接数等)来帮助,否则你将不得不在你的应用程序代码中写这个。
Oracle善于允许reads to bypass writes,但是SqlServer并不像标准版那样......
因此我会将存储过程拆分为使用两个事务,第一个事务应该只是:
并使用第二个(希望非常短)的交易
(您可以使用“in”在单个更新语句中进行上述操作,然后检查预期的行数是否已更新)
对不起,有时您需要了解每次交易的内容以及锁定的详细信息。
如果表格较小,那么 更新更短,锁定 保持更短的时间。
因此,请考虑拆分表:
答案 4 :(得分:0)
以下是一些想法:
我假设已经优化了T-SQL,索引,事务大小等。
如果有帮助,我会在书中详细讨论这个主题(包括SSD,磁盘阵列优化等) - Ultra-Fast ASP.NET。