2013-06-11 7 views
5

Nie jest dla mnie jasne (czytając dokumenty MySQL), czy następujące zapytanie uruchomione na tabelach INNODB w MySQL 5.1, spowoduje utworzenie WRITE LOCK dla każdego wiersza bazy danych aktualizacje wewnętrznie (łącznie 5000) lub ZABLOKUJ wszystkie wiersze w partii. Ponieważ baza danych ma naprawdę duże obciążenie, jest to bardzo ważne.AKTUALIZACJA za pomocą SELECT, spowoduje zablokowanie każdego wiersza lub wszystkich wybranych rekordów

UPDATE `records` 
INNER JOIN (
    SELECT id, name FROM related LIMIT 0, 5000 
) AS `j` ON `j`.`id` = `records`.`id` 
SET `name` = `j`.`name` 

będę oczekiwać, że będzie w rzędzie, ale jak ja nie wiem, aby upewnić się, że jest tak, zdecydowałem się poprosić kogoś z głębszej wiedzy. Jeśli tak nie jest, a db zablokuje wszystkie wiersze w zestawie, byłbym wdzięczny, gdybyś dał mi wyjaśnienie, dlaczego.

+0

Czy korzystasz z transakcji? (autocommit = off)? ps: czy jesteś pewien, że twoje zapytanie jest semantycznie poprawne? – Sebas

+0

Prawdopodobnie zablokuje wszystkie wiersze, ponieważ tak właśnie działa MySQL. – GolezTrol

+0

Och, czekaj, zależy to oczywiście od rodzaju stołu: http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html – GolezTrol

Odpowiedz

3

Wykonuje operację UPDATE - jest to operacja atomic, co oznacza, że ​​jeśli jeden z wierszy ulegnie awarii (na przykład z powodu unikalnego ograniczenia), nie zaktualizuje żadnego z 5000 wierszy. Jest to jedna z właściwości ACID transakcyjnej bazy danych.

Z tego powodu UPDATE przytrzymaj blokadę wszystkich wierszy dla całej transakcji. W przeciwnym razie inna transakcja może dalej aktualizować wartość wiersza, na podstawie jego bieżącej wartości (powiedzmy aktualizacji rekordów set value = value * "2"). Oświadczenie to powinno dawać inny wynik w zależności od tego, czy pierwsza transakcja zostanie zatwierdzona czy wycofana. Z tego powodu należy poczekać, aż pierwsza transakcja zakończy wszystkie 5000 aktualizacji.

Jeśli chcesz zwolnić blokady, po prostu wykonaj aktualizację w (mniejszych) partiach.

P.S. autocommit kontroluje, czy każda instrukcja jest wydana we własnej transakcji, ale nie wpływa na wykonanie pojedynczego zapytania.

Powiązane problemy