我有一个名为Products的表,它有很多列。
这是一个用于报告目的的临时表。数据将通过多个用户请求同时处理到此表。(单独存储过程对此表进行DML操作)
表格结构: 创建表产品 (实例uniqueidentifier, 插入日期时间, col1,col2,...)
插入的列将使用GETDATE()填充,以便在插入数据时使用。实例列具有newid()值。一个用户请求将具有一个唯一ID;可能有百万行。以下是将同时执行的查询,这会导致死锁。请告诉我
查询1: "设置事务隔离readuncommitted 从产品中删除P(Nolock)其中instance =' XXXX-xxx-xxx-xx'"
QUERY2: "设置事务隔离readuncommitted 从产品中删除P(Nolock),其中插入< = DATEADD(hh,-10,getdate())"
注意:非聚集索引是在实例列上创建的。
请告诉我在这种情况下我可以使用哪种锁。
注意我无法使用主键,因为当我向表中插入1000万行时(这是一个事务;有20个并发转换)消耗时间。 该报告应该尽快生成。我的程序有多个35个DML语句,大约有15个DELETE语句用于实例列和其他列(表格中的DElete,其中instance = @instance和col1 = @ col1)。
答案 0 :(得分:5)
(1)您应该停止使用read uncommitted
隔离。至少使用read committed
。
(2)您可以尝试避免死锁,例如确保您的不同事务以相同的顺序访问数据库对象等等。这值得一读 - http://support.microsoft.com/kb/169960
(3)禁用表的锁升级(更细粒度的锁,以便更好的并发性,但更多的锁开销):
ALTER TABLE Products SET (lock_escalation = disable)
(4)禁止页面锁定,并允许索引上的行锁定(意味着您无法对索引进行碎片整理,但仍可以重建它们):
ALTER INDEX [<YourIndex>] ON Product WITH (allow_row_locks = on, allow_page_locks = off)
答案 1 :(得分:1)
首先,除了独占锁之外,你无法对这些删除语句采取锁定。您的isolation level and NOLOCK
hints are being ignored by Sql Server:
(Nolock)仅适用于
SELECT
声明。
两个建议:
将instance
上的非聚集索引更改为聚簇索引。但是,只有在您将NEWID()
更改为NEWSEQUENTIALID()
时才能执行此操作。
其次,不要执行delete
来删除超过10小时的记录......请考虑implementing rolling partitions。这将删除您使用其他delete
操作清理所造成的任何争用。