Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Hướng dẫn sử dụng núm vú giả để khóa trong innodb

Dưới đây là những lưu ý của tôi khi làm việc với bộ phận hỗ trợ MySQL về một vấn đề khóa lạ gần đây (phiên bản 5.1.37):

Tất cả các hàng và mục nhập chỉ mục được duyệt qua để đến các hàng đang được thay đổi sẽ bị khóa. Nó được bảo hiểm tại:

http://dev.mysql.com/doc /refman/5.1/en/innodb-locks-set.html

"Khóa đọc, CẬP NHẬT hoặc XÓA thường thiết lập khóa bản ghi trên mọi bản ghi chỉ mục được quét trong quá trình xử lý câu lệnh SQL. Không quan trọng liệu có điều kiện WHERE trong câu lệnh loại trừ hàng hay không. InnoDB thực hiện không nhớ điều kiện WHERE chính xác, nhưng chỉ biết phạm vi chỉ mục nào đã được quét. ... Nếu bạn không có chỉ mục nào phù hợp với câu lệnh của mình và MySQL phải quét toàn bộ bảng để xử lý câu lệnh, mọi hàng của bảng sẽ bị khóa, chuyển khối tất cả chèn của người dùng khác vào bảng. "

Nó là. Một giải pháp thường hữu ích là thực hiện:

CẬP NHẬT bất kỳ bảng nào đặt bất kỳ thứ gì thành một cái gì đó có khóa chính trong (chọn khóa chính từ bảng nào có ràng buộc sắp xếp theo khóa chính);

Lựa chọn bên trong không cần phải khóa và bản cập nhật sau đó sẽ có ít công việc hơn để cập nhật. Mệnh đề theo thứ tự đảm bảo rằng cập nhật được thực hiện theo thứ tự khóa chính để khớp với thứ tự vật lý của InnoDB, đây là cách nhanh nhất để thực hiện.

Trong trường hợp có số lượng lớn các hàng, như trong trường hợp của bạn, tốt hơn là nên lưu trữ kết quả đã chọn trong một bảng tạm thời có thêm cột cờ. Sau đó chọn từ bảng tạm thời không đặt cờ để lấy từng đợt. Chạy các bản cập nhật với giới hạn là 1000 hoặc 10000 và đặt cờ cho lô sau khi cập nhật. Các giới hạn sẽ giữ cho số lượng khóa ở mức có thể chấp nhận được trong khi công việc đã chọn sẽ chỉ phải thực hiện một lần. Cam kết sau mỗi đợt sẽ giải phóng ổ khóa.

Bạn cũng có thể tăng tốc độ công việc này bằng cách thực hiện tổng chọn lọc của một cột không được lập chỉ mục trước khi thực hiện từng đợt cập nhật. Thao tác này sẽ tải các trang dữ liệu vào vùng đệm mà không cần khóa. Sau đó, khóa sẽ kéo dài trong một khoảng thời gian ngắn hơn vì sẽ không có bất kỳ lần đọc đĩa nào.

Điều này không phải lúc nào cũng thực tế nhưng khi có nó có thể rất hữu ích. Nếu bạn không thể thực hiện theo lô, ít nhất bạn có thể thử lựa chọn trước để tải trước dữ liệu, nếu dữ liệu đủ nhỏ để vừa với vùng đệm.

Nếu có thể, hãy sử dụng chế độ cách ly giao dịch READ COMMITTED. Xem:

http://dev.mysql.com/doc/refman /5.1/en/set-transaction.html

Để có được việc giảm khóa đó, yêu cầu sử dụng ghi nhật ký nhị phân dựa trên hàng (thay vì ghi nhật ký nhị phân dựa trên câu lệnh mặc định).

Hai vấn đề đã biết:

  1. Các truy vấn con đôi khi có thể ít hơn mức tối ưu hóa lý tưởng. Trong trường hợp này, đó là một truy vấn phụ phụ thuộc không mong muốn - đề xuất mà tôi đưa ra để sử dụng một truy vấn con hóa ra không hữu ích so với phương án thay thế trong trường hợp này vì điều đó.

  2. Xóa và cập nhật không có cùng phạm vi kế hoạch truy vấn như các câu lệnh đã chọn, vì vậy đôi khi rất khó để tối ưu hóa chúng một cách chính xác mà không đo lường kết quả để tìm ra chính xác những gì chúng đang làm.

Cả hai điều này đang dần được cải thiện. Lỗi này là một ví dụ mà chúng tôi vừa cải thiện các tính năng tối ưu có sẵn cho một bản cập nhật, mặc dù những thay đổi là rất quan trọng và nó vẫn đang được kiểm tra chất lượng để đảm bảo rằng nó không có bất kỳ tác dụng phụ lớn nào:

http://bugs.mysql.com/bug.php?id=36569




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL GROUP_CONCAT thoát

  2. Làm thế nào để có được một thứ hạng hàng?

  3. com.mysql.jdbc.exceptions.MySQLSyntaxErrorException khi sử dụng PreparedStatement

  4. Sai về độ chính xác thập phân của MySQL &PHP

  5. Các phương pháp hay nhất để tối ưu hóa trang web LAMP để tăng tốc độ?