Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Deadlocks beim Löschen von Zeilen durch MySQL

Beim Ausführen von DML Operationen, InnoDB sperrt alle gescannten, nicht übereinstimmenden Zeilen.

Betrachten Sie dieses Tabellenlayout:

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;

In diesem Fall MySQL wählt RANGE Zugriffspfad auf id , die er für günstiger hält als REF auf data .

In einer gleichzeitigen Transaktion können Sie die Zeilen 6 löschen oder aktualisieren , 7 , 8 aber nicht Zeilen 1 bis 5 da sie gesperrt sind (obwohl nur Zeile 2 war betroffen).

Wenn Sie id <= 5 entfernen aus der obigen Bedingung können Sie jede Zeile außer Zeile 3 löschen .

Leider können Sie MySQL nicht steuern Zugriffspfade in DML Operationen.

Das Beste, was Sie tun können, ist, Ihre Bedingungen richtig zu indizieren und zu hoffen, dass MySQL wählt diese Indizes aus.