2013-06-11 24 views
5

Không rõ ràng với tôi (bằng cách đọc tài liệu MySQL) nếu truy vấn sau chạy trên bảng INNODB trên MySQL 5.1, sẽ tạo WRITE LOCK cho mỗi hàng db cập nhật nội bộ (5000 trong tổng số) hoặc LOCK tất cả các hàng trong lô. Vì cơ sở dữ liệu có tải nặng, điều này rất quan trọng.CẬP NHẬT với CHỌN, nó sẽ khóa mỗi hàng hoặc tất cả các hồ sơ được chọn

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

Tôi mong rằng nó sẽ là một hàng nhưng vì tôi không biết cách đảm bảo, tôi quyết định hỏi ai đó có kiến ​​thức sâu hơn. Nếu đây không phải là trường hợp và db sẽ KHÓA tất cả các hàng trong tập hợp, tôi sẽ biết ơn nếu bạn cho tôi giải thích lý do tại sao.

+0

Bạn đang sử dụng giao dịch? (autocommit = off)? ps: bạn có chắc là truy vấn của bạn là correcT semantically? – Sebas

+0

Nó có thể sẽ khóa tất cả các hàng, bởi vì đó là cách MySQL cuộn. – GolezTrol

+0

Ồ chờ đã, nó phụ thuộc vào loại bảng, tất nhiên: http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html – GolezTrol

Trả lời

3

UPDATE đang chạy trong giao dịch - đó là hoạt động atomic, có nghĩa là nếu một trong các hàng không thành công (vì hạn chế duy nhất chẳng hạn), nó sẽ không cập nhật bất kỳ hàng nào trong số 5000 hàng. Đây là một trong các thuộc tính ACID của một cơ sở dữ liệu giao dịch.

Vì điều này, UPDATE giữ khóa trên tất cả các hàng cho toàn bộ giao dịch. Nếu không, một giao dịch khác có thể tiếp tục cập nhật giá trị của một hàng, dựa trên giá trị hiện tại của nó (giả sử cập nhật giá trị thiết lập giá trị = giá trị * '2'). Tuyên bố này sẽ tạo ra kết quả khác nhau tùy thuộc vào giao dịch đầu tiên cam kết hoặc quay lại. Vì điều này nên đợi giao dịch đầu tiên hoàn thành tất cả 5000 bản cập nhật.

Nếu bạn muốn nhả khóa, chỉ cần cập nhật các lô (nhỏ hơn).

P.S. autocommit kiểm soát nếu mỗi câu lệnh được phát hành trong giao dịch riêng, nhưng không ảnh hưởng đến việc thực hiện một truy vấn đơn lẻ

Các vấn đề liên quan