私はテーブルと言います
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 |
クエリは TABLE ACCESS FULL を2回実行しているため、同じクエリを実行する2つのセッションが異なる順序で行にアクセスすると思われます。
列のインデックス作成は、デッドロックの防止に役立ちますか? NEXT にインデックスを作成するとしますか??? または、PRIMARY を NON CLUSTERED KEY に変更することによって?? 注: 通常、テーブルには最大 1000 行が含まれます。