按位运算符是否会导致正常比较不锁定的锁定?

问题描述:

我有一个SQL脚本一直在导致死锁的问题,我想知道是否有某种特殊的锁应用于按位操作时。按位运算符是否会导致正常比较不锁定的锁定?

有问题的查询是这样的:

UPDATE pos.prices SET active = 1 WHERE NOT (Attributes & 1 = 1) 

与活性BIT列类型和属性TINYINT

原因是,其他脚本的更新不包括按位AND(&)执行没有问题。这是此操作的唯一更新,它是死锁。

查询是死锁是一个大的,周期性的选择与多个连接抓住SCHEMA锁。

编辑:此查询是否会避免表扫描?

UPDATE pos.prices SET active = 1 WHERE id in 
(SELECT id FROM 
(SELECT id, (Attributes & 1) as IsLocked FROM pos.prices) as t1 
WHERE NOT IsLocked = 1) 
+1

一个可能的差异是,按位测试需要使用表扫描来评估每行的按位操作。您的示例中索引将不起作用。 – hatchet 2013-02-11 18:11:09

+0

那么,你需要一个表锁来做更新,并且你的表中每个记录都有一个偶数编号的属性值,所以我想这取决于你的pos.prices表有多大。如果它很大,那么它是有道理的。快速运行的操作是否具有更多限制条件,并且可以使用索引? – 2013-02-11 18:12:00

+0

@ Love2Learn我不知道什么是合格的,但表格通常在500-2000条记录的范围内。大多数其他更新都是针对特定行的PK或所有行。 – 2013-02-11 18:26:09

任何对where子句中的列进行计算的操作都会阻止该列的索引使用。这导致了表扫描。虽然表扫描不一定会产生死锁,但它可以显着提高其概率。

+0

如果我把计算放在'SELECT'而不是'WHERE'中,是否可以避免这个问题?我编辑了这个问题来展示一个例子。 – 2013-02-11 18:22:12

+0

@ MalcolmO'Hare如果这有什么区别,我会感到惊讶。查询优化器具有足够的灵活性,这两个版本可以很好地解决相同的计划。 – hatchet 2013-02-11 18:29:26