首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计基于预留的表的最佳方法

设计基于预留的表的最佳方法
EN

Stack Overflow用户
提问于 2009-09-22 14:02:07
回答 5查看 645关注 0票数 2

我的一个客户有一个基于预订的系统。类似于航空公司。在MS SQL 2005上运行。

上一家公司设计它的方式是将分配创建为一组行。

简单的例子是:

代码语言:javascript
复制
AllocationId | SeatNumber | IsSold

1234         | A01        | 0

1234         | A02        | 0

在出售座位的过程中,系统会在桌子上建立一个更新锁。

目前我们有一个问题,锁定过程运行缓慢,我们正在寻找加速它的方法。

表已经被有效地索引,所以我们正在寻找一种硬件解决方案来加速这一过程。该表大约有500万个活动行,位于RAID 50 SAS阵列上。

我假设当你有5百万行并且一次更新2-5行时,硬盘寻道时间将是加速更新锁的限制因素(我可能是错的)。

我听说有人在几个磁盘阵列上使用索引分区,有没有人有过类似的加速锁定的经历?谁能给我一些建议,关于哪些硬件可以升级,或者我们可以利用哪些技术来加快更新锁定(而不移动到集群)的可能解决方案?

EN

回答 5

Stack Overflow用户

发布于 2009-10-12 09:05:54

最后一次尝试…

很明显,有太多的锁持有的时间太长。

一旦系统由于太多的锁而开始变慢,启动更多事务就没有意义了。

因此,您应该对系统进行基准测试,以找出最优的并发事务数量,然后使用一些队列系统(或其他方式)来限制并发事务的数量。Sql Server可能有一些设置(活动连接数等)可供帮助,否则您将不得不在应用程序代码中编写此设置。

Oracle在允许reads to bypass writes方面做得很好,但是SqlServer并不是很标准...

因此,我会将存储的proc拆分为使用两个事务,第一个事务应该是:

读取未提交(or

  • ) transaction
  • find您想要销售的座位所在行的“Id”。
  • 然后您应该提交(或中止)此事务,

并使用第二个(希望非常短)事务

行最有可能是读提交的(或者可能对每一行进行更新(使用在此期间尚未售出的locking hint)

  • Check (如果已售出,则中止并重新启动))

上设置“IsSold”标志

(您可以使用“in”在一条update语句中执行上述操作,然后检查预期的行数是否已更新)

对不起,有时你确实需要理解事务的每一次都做了什么,以及锁是如何工作的细节。

如果表较小,则更新时间较短,锁持有的时间也较短。

因此,请考虑拆分表:

  • ,所以你有一个只包含“AllocationId”和“IsSold”的表。
  • 此表可以存储为单个btree (在AllocationId)
  • As上按索引组织的表所有其他索引将位于与座位详细信息冲突的表上,更新不应锁定任何索引。
票数 1
EN

Stack Overflow用户

发布于 2009-09-22 14:38:24

我认为您不会从表分区中获得任何好处--唯一的改进是从较小(较短)的索引树中读取较少的磁盘(每次读取将至少命中索引的每个级别一次,因此级别越少,读取速度越快)。但是,我得到了一个带有4M+行分区的表,它在4列上进行索引,键长度净为10字节。它适用于三个索引级别,最高级别为42.6%。假设您有类似的东西,分区可能只从树中删除一个级别,这似乎是合理的,我怀疑这是一个很大的改进。

一些即兴的强硬想法:

由于奇偶校验计算,Raid 5(和50)的写入速度可能会较慢。如果磁盘I/O缓存足够大,可以处理工作负载,这不是问题(或者我是这么被告知的),但是如果磁盘I/O缓存被淹没,您可能需要考虑raid 10。

跨多个驱动器阵列对表进行分区。使用两个(或更多) Raid阵列,将表分布在卷文件/文件组中,无论是否使用表分区或分区视图,您都可以获得两倍的磁盘I/O速度,这取决于数据相对于检索数据的查询所在的位置。(如果数组#1和数组#2上的所有内容都是空闲的,那么您什么也得不到。)

最坏的情况是,可能有尖端或尖端的技术会让你大吃一惊。如果它对你的业务至关重要,而且你有预算,那么可能值得认真研究一下。

票数 0
EN

Stack Overflow用户

发布于 2009-09-22 14:57:30

long持有的更新锁的长度

为什么“table”上的锁而不仅仅是“rows”上的锁被出售?

如果锁被持有超过一小部分秒,这很可能是你的问题。SqlServer不喜欢你在用户填写网页表单时手持锁,等等。

使用SqlServer,您必须自己实现“购物车”,通过临时预订座位,直到用户支付为止。例如,添加“IsReserved”和“ReservedAt”列,则任何已预订超过n分钟的座位都应自动取消预订。

这是一个很难解决的问题,因为购物者不会期望库存中的座位会被卖给他结账的其他人。然而,你不知道购物者是否会完成结账。那么如何在UI上显示它呢?考虑一下其他预订网站做了什么,然后复制一个你的用户已经知道如何使用的网站。

(Oracle有时可以处理长时间保存的锁,但如果保持短时间的锁定,即使是Oracle也比快得多,也更好。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1460294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档