sql >> Database teknologi >  >> RDS >> Mysql

INSERT ... SELECT, InnoDB og låsning

Det er korrekt. Rækkerne i tabellen, der læses fra, er låst med en delt lås (SELECT er implicit LÅS I DELE-TILSTAND ). Der er ingen måde at undgå dette på. Det er sådan set det, du beder systemet om:kopier alle rækker, der matcher en betingelse. Den eneste måde at sikre, at det faktisk er alle rækker, der matcher betingelsen, og at listen ikke ændres under eller umiddelbart efter udførelsen af ​​den sætning, er at låse rækkerne.

Som en afklaring vedrørende hvorfor du ikke er i stand til at INSERT med group_id =2 :

Dette har at gøre med, at din forespørgsel specifikt er WHERE group_id =3 OG oprettet <'2014-01-04'KEY group_id_created (gruppe_id, oprettet) . For at søge i alle rækker, der matcher group_id =3 OG oprettet <'2014-01-04' indekset vil blive krydset baglæns begyndende med den første række, der overskrider denne betingelse, den øvre grænse, som er (3, '2014-01-14') og fortsætter, indtil du finder en række, der ikke matcher betingelsen, som siden oprettet har ingen nedre grænse vil være den første række hvor gruppe_id <3 hvilket selvfølgelig er group_id =2 .

Det betyder, at den første række stødte på group_id =2 er også låst, hvilket vil være rækken med den maksimale oprettede værdi. Dette vil gøre det umuligt at INSERT ind i "gabet" mellem (2, MAX(created)) og (3, MIN(oprettet)) (ikke ordentlig SQL selvfølgelig, bare pseudo-SQL), selvom dette ikke specifikt er en "gap lock".




  1. laravel 4 - hvordan begrænser (tag og spring) for veltalende ORM?

  2. MySQL bitvise operationer, bloom filter

  3. MySQL – FOUND_ROWS() Funktion for det samlede antal berørte rækker

  4. Opdater html-siden, når en ny sql-indgang er blevet indtastet