CHỌN ĐỂ CẬP NHẬT MySQL

CHỌN … ĐỂ CẬP NHẬT có tác dụng phụ (không quá) đáng ngạc nhiên đối với các hàng không tồn tại. nó có thể gây ra một hình phạt hiệu suất (nghiêm trọng) và thậm chí ngăn cản bạn chèn hàng mới

Khóa hàng để cập nhật

Nhóm phát triển của chúng tôi đang làm việc trên một ứng dụng cần đảm bảo cập nhật trên một mục hàng không bị sửa đổi bởi một giao dịch khác. Đương nhiên, họ bắt đầu sử dụng CHỌN … ĐỂ CẬP NHẬT để khóa hàng trước khi cập nhật nó. Điều này hoạt động tuyệt vời để ngăn bất kỳ ai khác cập nhật hàng này. Tuy nhiên, họ bắt đầu nhận được một số thời gian chờ khóa trên các phần chèn mới của các mục hoàn toàn không liên quan trong quá trình kiểm tra tải và họ đã yêu cầu tôi xem xét vấn đề này

SELECT … FOR UPDATE được mô tả như sau trong tài liệu MySQL.
______0
Cho đến giờ vẫn ổn. hành vi này dự kiến ​​sẽ xảy ra. Nó cũng không đề cập đến bất cứ điều gì về việc khóa bất cứ thứ gì ngoại trừ các hàng mà nó đọc.

Tôi đã hỏi nhóm liệu họ có đang cố gắng chèn cùng một dữ liệu khi họ đang khóa trong giao dịch khác hay không và họ nói rằng họ không cố gắng.

Trong mã giả, họ đã làm điều này.
______1
Cột uuid ở đây là khóa chính của bảng. Mã này thực thi tốt và không có vấn đề gì khi chỉ là một giao dịch.

Bạn có thể thắc mắc tại sao không sử dụng lệnh INSERT … ON DUPLICATE KEY UPDATE hoặc REPLACE INTO?
Trước hết, chúng tôi chỉ thỉnh thoảng mới chèn, vì vậy 99% lệnh chèn sẽ không thực hiện được . Thứ hai, chúng tôi chỉ có thể cập nhật một cột trong một hàng, do đó, điều đó có nghĩa là chúng tôi cần biết toàn bộ hàng trước khi chúng tôi phải chèn hoặc thay thế hàng.

Không có hàng để cập nhật

Bây giờ điều gì sẽ xảy ra nếu không có hàng nào để cập nhật?

Theo mô tả trong tài liệu MySQL, nó đặt một khóa độc quyền trên mỗi hàng mà nó đọc, nhưng khi không có hàng nào để đọc thì sao? .
______2
Nếu không có hàng, khóa sẽ vẫn được đặt trên các mục nhập chỉ mục được liên kết. Điều này không nên xấu, phải không? . nó không phải là một khóa khoảng cách một mình, mà là một.

Vì khóa được đặt trên mục nhập chỉ mục không tồn tại nên khóa phím tiếp theo được tạo. Tùy thuộc vào nơi bạn sẽ chèn vào chỉ mục, bạn có thể thấy toàn bộ phạm vi bị khóa vì nó cần chèn trong phạm vi này. Trong phiên bản UUID của chúng tôi, điều này không xảy ra thường xuyên vì có một yếu tố ngẫu nhiên, nhưng nó vẫn có thể xảy ra thường xuyên nếu bạn chỉ có một vài hàng trong bảng của mình. Trong trường hợp đó, khoảng cách giữa các UUID lớn và do yếu tố ngẫu nhiên, yu cuối cùng có thể khóa các khoảng trống lớn trong chỉ mục. Vì độ trễ giữa các khu vực xuất hiện trên hệ thống này, điều này giúp khóa phím tiếp theo mở lâu hơn và khả năng xảy ra va chạm trong khoảng cách cũng tăng lên một chút. Vì vậy, điều đó giải thích hành vi trong quá trình kiểm tra tải. Vì vậy, tất cả đều tốt, kết thúc tốt đẹp?

Tác dụng phụ khó chịu của khóa Next-Key

Có một tác dụng phụ khó chịu với khóa phím tiếp theo. nếu giá trị chỉ mục sẽ lớn hơn giá trị lớn nhất trong bảng, nó sẽ khóa mọi thứ trên giá trị lớn nhất cho đến vô cùng

Vậy điều gì sẽ xảy ra với một bảng trong đó khóa chính là thứ tự giống như một số nguyên? .
______3
Điều này sẽ tạo ra khoảng cách từ 5 đến 10 và khoảng cách từ 15 đến vô cùng.

Khi chúng tôi đang chọn trong khoảng trống giữa 5 và 10, chúng tôi tạo khóa phím tiếp theo trong khoảng từ 5 đến 10 và chúng tôi không thể chèn các hàng mới vào trong khoảng trống này. Tuy nhiên, chúng ta vẫn có thể chèn các hàng mới vào cuối bảng. Tuy nhiên, nếu chúng tôi chọn một hàng trên id lớn hơn 15, chúng tôi sẽ đặt khóa phím tiếp theo từ 15 đến vô cùng. Điều này có nghĩa là không ai có thể thêm bất cứ thứ gì vào bảng này nữa cho đến khi chúng tôi thực hiện giao dịch của mình. Điều này có thể trở thành nút cổ chai nghiêm trọng nếu bạn chèn nhiều hàng hơn cập nhật

Phần kết luận

Tôi không biết rằng CHỌN … ĐỂ CẬP NHẬT thực sự đã khóa chỉ mục cho các hàng chưa tồn tại. Tôi đã lý luận rằng nếu không có hàng nào được chọn thì sẽ không có gì để khóa. Và nếu không có gì để khóa, thì toàn bộ CHỌN … ĐỂ CẬP NHẬT sẽ đơn giản là xì hơi

Tại sao nên sử dụng CHỌN để cập nhật?

Câu lệnh CHỌN ĐỂ CẬP NHẬT được sử dụng để sắp xếp các giao dịch bằng cách kiểm soát quyền truy cập đồng thời vào một hoặc nhiều hàng của bảng . Nó hoạt động bằng cách khóa các hàng được trả về bởi một truy vấn lựa chọn, sao cho các giao dịch khác đang cố truy cập vào các hàng đó buộc phải đợi giao dịch đã khóa các hàng kết thúc.

Làm thế nào để sử dụng để cập nhật trong MySQL?

Cú pháp lệnh cập nhật MySQL . SET `column_name` = `new_value' là tên và giá trị của các trường bị ảnh hưởng bởi truy vấn cập nhật. Lưu ý, khi đặt giá trị cập nhật, kiểu dữ liệu chuỗi phải nằm trong dấu nháy đơn

Chúng ta có thể sử dụng CHỌN và cập nhật cùng nhau không?

Cấu trúc truy vấn, “CẬP NHẬT từ CHỌN” có thể được sử dụng để thực hiện loại tình huống cập nhật dữ liệu này . Ngoài ra, chúng ta có thể sử dụng các câu lệnh MERGE thay thế và các phương thức truy vấn con.

Truy vấn cập nhật trong SQL là gì?

Một câu lệnh UPDATE SQL thay đổi dữ liệu của một hoặc nhiều bản ghi trong một bảng. Tất cả các hàng có thể được cập nhật hoặc một tập hợp con có thể được chọn bằng một điều kiện. Câu lệnh UPDATE có dạng sau. CẬP NHẬT tên_bảng SET tên_cột = giá trị [, tên_cột = giá trị. ]