2013-06-11 20 views
5

Aşağıdaki sorgu MySQL 5.1'de INNODB tablolarında çalıştırılırsa (MySQL belgelerini okuyarak), satırların her biri için WRITE LOCK yaratacağı açık değildir. dahili olarak güncelleştirir (toplamda 5000) veya toplu işteki tüm satırları LOCK. Veritabanının gerçekten ağır yükü olduğundan, bu çok önemlidir.SELECT ile UPDATE, her satırı veya tüm SELECTed kayıtları kilitler

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

Eminim o kadar olduğundan emin olmak için bir yol bilmiyorum gibi satır başına olabilir ama beklediğiniz, ben daha derin bilgiye sahip birini istemeye karar verdi. Bu durumda ve db sette tüm satırları LOCK olurdu, bana neden açıklama verirseniz teşekkür ederim.

+0

İşlemler kullanıyor musunuz? (autocommit = kapalı)? ps: sorgunuzun semantically correcT olduğundan emin misiniz? – Sebas

+0

Muhtemelen tüm satırları kilitler, çünkü MySQL bu şekilde alır. – GolezTrol

+0

Bekleyin, tablonun türüne bağlıdır, elbette: http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html – GolezTrol

cevap

3

UPDATE, atomic işleminde çalışıyor - bu, satırlardan biri başarısız olursa (örneğin benzersiz kısıtlama nedeniyle) 5000 satırdan herhangi birini güncelleştirmeyeceği anlamına gelir. Bu işlem veritabanının ACID özelliklerinden biridir.

Bu nedenle, UPDATE tüm işlem için tüm satırların üzerinde bir kilit tutar. Aksi takdirde, başka bir işlem, mevcut değerine bağlı olarak bir satırın değerini daha da güncelleyebilir (güncelleme kayıtlarının değeri = değer * '2' diyelim). Bu ifade, ilk işlemin tamamlanıp geri alınmasına bağlı olarak farklı sonuçlar üretmelidir. Bu nedenle, ilk işlemin 5000 güncellemeyi tamamlamasını beklemek gerekir.

Kilitleri serbest bırakmak isterseniz, güncellemeyi (daha küçük) toplu işlerde yapın.

P.S. autocommit, her ifadenin kendi işleminde verildiğini denetler, ancak tek bir sorgunun yürütülmesini etkilemezse