Oracle SELECT FOR UPDATE查询中的死锁

Oracle SELECT FOR UPDATE查询中的死锁,oracle,oracle11g,database-deadlocks,Oracle,Oracle11g,Database Deadlocks,我有话要说 TAB1 ID, TARGET, STATE, NEXT 列ID是主键 显示死锁的查询与此类似 SELECT * FROM TAB1 WHERE NEXT = (SELECT MIN(NEXT) FROM TAB1 WHERE TARGET=? AND STATE=?) FOR UPDATE 我做了一个解释计划,我看到这样的情况: | Id | Operation | Name | Rows | Bytes | Cost (%CP

我有话要说

TAB1

ID, TARGET, STATE, NEXT
ID
是主键

显示死锁的查询与此类似

SELECT * 
FROM TAB1 
WHERE NEXT = (SELECT MIN(NEXT) FROM TAB1 WHERE TARGET=? AND STATE=?) FOR UPDATE
我做了一个解释计划,我看到这样的情况:

| Id  | Operation             | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |               |     1 |  8095 |     6   (0)| 00:00:01 |
|   1 |  FOR UPDATE           |               |       |       |            |          |
|   2 |   BUFFER SORT         |               |       |       |            |          |
|*  3 |    TABLE ACCESS FULL  | TAB1          |     1 |  8095 |     3   (0)| 00:00:01 |
|   4 |     SORT AGGREGATE    |               |     1 |  2083 |            |          |
|*  5 |      TABLE ACCESS FULL| TAB1          |     1 |  2083 |     3   (0)| 00:00:01 |
由于查询执行了两次完全表访问,所以我怀疑执行同一查询的两个会话将以不同的顺序访问行


列的索引是否有助于防止死锁?比如说在下一步创建索引???或者通过将主密钥更改为非群集密钥??注意:通常情况下,该表最多有1000行。

在下一列添加非聚集索引确实会提高性能并减少死锁问题。

SQL只是结构化查询语言—许多数据库系统都使用这种语言,但不是数据库产品。。。许多事情都是特定于供应商的-因此我们确实需要知道您使用的是什么数据库系统(以及哪个版本)(请相应地更新标记)…您可能会在这里出现死锁,索引也不会有帮助,请提供更多信息-您想做什么?我假设您没有索引。会建议在目标/状态上使用一个,可能是下一个(这是一个索引),在下一个上使用一个单独的索引。但是,有更有效的方法可以做到这一点,而无需再次扫描表格。当您锁定桌子时,没有任何东西可以阻止锁定。唯一的解决方案是不锁定表,或者让其他查询使用
nowait
,以便它们忽略锁定的行。无需猜测是哪些查询导致死锁。每个死锁都将生成一个跟踪文件,该跟踪文件将准确地告诉您是什么语句导致了问题。如果您知道其中一个死锁发生的确切时间,请要求DBA查找当时生成的跟踪文件。请显示整个事务-->在提交之前事务执行的所有命令。跟踪显示<代码>选择*。。。对于UPDATE,但这不一定是死锁的主要原因。减少,但不是消除,我想是mysql,所以如果表中有多行具有相同的下一个值,此查询有时会产生死锁,您可能会错误地怀疑@IlyaBursov,这是Oracle,标记为Oracle和SQL Server,而不是MySQL。为什么在下一列添加索引会有帮助?您仍然需要计算谓词。是否需要为目标和状态列编制索引?我认为MIN()正在进行完全扫描,然后WHERE子句也在进行扫描,因为WHERE子句中没有主键。下一个值是System.currentTimeMillis()。因此,具有相同NEXT的行是最简单的。@Ben,主要查询谓词使用NEXT列。这就是为什么它应该做点什么。