При выполнении операций DML
, InnoDB
блокирует все отсканированные строки, не сопоставленные.
Рассмотрим эту раскладку таблицы:
DROP TABLE t_tran;
CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;
DROP TABLE t_tran;
CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;
INSERT
INTO t_tran
VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8);
START TRANSACTION;
DELETE
FROM t_tran
WHERE data = 2
AND id <= 5;
В этом случае MySQL
выбирает RANGE
путь доступа на id
, который он считает дешевле, чем REF
на data
.
В параллельной транзакции вы сможете удалять или обновлять строки 6
, 7
, 8
, но не строки 1
до 5
, поскольку они заблокированы (несмотря на то, что только строка 2
пострадали).
Если вы удалите id <= 5
из указанного выше условия, вы сможете удалить любую строку, кроме строки 3
.
К сожалению, вы не можете контролировать MySQL
путей доступа в DML
операциях.
Лучшее, что вы можете сделать, - правильно проиндексировать ваши условия и надеяться, что MySQL
выберет эти индексы.