我们有一个存储过程,可以加载订单的订单详细信息。我们总是想要有关订单的最新信息,因此每次调用存储过程时都会重新生成订单的订单详细信息。我们正在使用SQL Server 2016.
伪代码:
当多个最终用户同时执行存储过程时,会在orderdetails
表上创建阻塞。第一个调用者完成后,第二个调用者排队,然后是第三个调用者。因此,随着时间的推移,生成orderdetails
的时间会增加。特别是在包含>中的详细信息行的大订单的情况下,会发生这种情况。 100k或1或200万,因为有桌面级锁定正在发生。
我们采取的方法
我们根据并发orderdetails
加载的订单标识符的最后一位数对表进行了分区。这样可以提高第一次orderdetails
加载时的性能,因为没有删除。但是,第二次,第一次会话中的INSERT
会阻止其他会话DELETE
。其他会话将被阻止,直到第一个会话完成INSERT
。
我们正在考虑为每个订单创建单独的orderdetails
表,以避免出现这种并发问题。
问题
您能否提出一些方法,以支持并发DELETE
& INSERT
场景?
答案 0 :(得分:2)
我们通过寻找orderdetails
的临时表解决了争用问题。我们发现大量查询花费的时间更长 SELECT ,这个更长的时间导致orderdetails
表上的表级锁更长。
因此,我们首先将数据加载到临时表#orderdetail
中,然后在orderdetail
表中进行DELETE和INSERT。
由于orderdetail
表已经分区, DELETE 更快, INSERT 并行发生。 INSERT 在这里也非常快,因为它是来自#orderdetail
表的简单表扫描。
答案 1 :(得分:1)
您可以查看Hekaton Engine。如果您使用SQL Server Standard Edition
,它甚至可以在SP1
中使用。
如果由于硬件或软件限制而导致实施过于复杂,您可以尝试使用数据库的Isolation Levels。有时,正在读取大量数据的查询被阻止,甚至是修改这些数据部分的查询的死锁受害者。您可以问自己,您是否需要保证用户读取的数据有效,或者您可以负担得起例如一些脏读?