sql >> Databáze >  >> RDS >> Mysql

INSERT ... SELECT, InnoDB a zamykání

To je správně. Řádky v tabulce, ze které se čte, jsou uzamčeny sdíleným zámkem (SELECT je implicitně LOCK IN SHARE MODE ). Neexistuje způsob, jak se tomu vyhnout. Je to něco, o co systém žádáte:zkopírujte všechny řádky, které odpovídají podmínce. Jediným způsobem, jak zajistit, že všechny řádky, které splňují podmínku a že se tento seznam nezmění během nebo bezprostředně po provedení daného příkazu, je uzamknout řádky.

Jako vysvětlení ohledně toho, proč nemůžete INSERT s group_id = 2 :

Souvisí to s tím, že váš dotaz je konkrétně WHERE group_id = 3 AND created < '2014-01-04' na KEY group_id_created (group_id, created) . Chcete-li vyhledat všechny řádky, které odpovídají group_id = 3 AND created < '2014-01-04' index bude procházet pozpátku počínaje prvním řádkem, který přesahuje tuto podmínku, horní mez, což je (3, '2014-01-14') a pokračujte, dokud nenajdete řádek, který neodpovídá podmínce, která byla od té doby created nemá dolní hranici bude první řádek, kde group_id < 3 což je samozřejmě group_id = 2 .

To znamená, že na prvním řádku bylo zjištěno group_id = 2 je také locked, což bude řádek s maximálním created hodnota. To znemožní INSERT do "mezery" mezi (2, MAX(created)) a (3, MIN(created)) (samozřejmě ne správné SQL, jen pseudo-SQL), i když se nejedná konkrétně o "zámek mezery".




  1. Jak správně indexovat propojovací tabulku pro připojení many-to-many v MySQL?

  2. Certifikace Oracle

  3. Oracle text escapující se složenými závorkami a zástupnými znaky

  4. Spuštění PostgreSQL pomocí Amazon RDS