そのとおりです。読み取られるテーブルの行は、共有ロック(SELECT
)でロックされます 暗黙的にLOCK IN SHARE MODE
)。これを回避する方法はありません。これは、システムに求めているものの一種です。条件に一致するすべての行をコピーします。実際に条件に一致するすべての行であり、そのステートメントの実行中または実行直後にそのリストが変更されないようにする唯一の方法は、行をロックすることです。
INSERT
ができない理由に関する説明として group_id = 2
を使用 :
これは、クエリが具体的にWHERE group_id = 3 AND created < '2014-01-04'
であることに関係しています。 KEY group_id_created (group_id, created)
で 。 group_id = 3 AND created < '2014-01-04'
を作成したすべての行を検索するには インデックスは、その条件の上限である(3, '2014-01-14')
を超える最初の行から逆方向にトラバースされます。 条件に一致しない行が見つかるまで続行します。これはcreated
以降です。 下限がない場合は、group_id < 3
の最初の行になります もちろん、これはgroup_id = 2
。
これは、group_id = 2
で最初の行が検出されたことを意味します また ロックされています。これは、created
が最大の行になります 価値。これにより、INSERT
が不可能になります (2, MAX(created))
の間の「ギャップ」に および(3, MIN(created))
(もちろん、適切なSQLではなく、疑似SQLだけです)。ただし、これは特に「ギャップロック」ではありません。