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

Bản cập nhật SQL có ảnh hưởng đến truy vấn con của nó trong quá trình chạy cập nhật không?

** Đã chỉnh sửa **

Chọn từ bảng mục tiêu

Từ 13.2.9.8. Truy vấn con trong Mệnh đề FROM:

Truy vấn con trong mệnh đề FROM có thể trả về vô hướng, cột, hàng hoặc bảng. Các truy vấn con trong mệnh đề FROM không thể là các truy vấn con tương quan, trừ khi được sử dụng trong mệnh đề BẬT của một hoạt động JOIN.

Vì vậy, có, bạn có thể thực hiện truy vấn trên.

Sự cố

Thực sự có hai vấn đề ở đây. Có sự đồng thời hoặc đảm bảo rằng không ai khác thay đổi dữ liệu từ dưới chân của chúng tôi. Điều này được xử lý bằng khóa. Xử lý việc sửa đổi thực tế các giá trị mới so với cũ bằng các bảng dẫn xuất.

Khóa

Trong trường hợp truy vấn của bạn ở trên, với InnoDB, MySQL thực hiện SELECT trước tiên và có được một khóa đọc (chia sẻ) trên từng hàng trong bảng riêng lẻ. Nếu bạn có mệnh đề WHERE trong câu lệnh SELECT, thì chỉ các bản ghi bạn chọn mới bị khóa, trong đó các phạm vi cũng sẽ khiến bất kỳ khoảng trống nào cũng bị khóa.

Khóa đọc ngăn không cho bất kỳ truy vấn nào khác có được khóa ghi, do đó, không thể cập nhật các bản ghi từ nơi khác trong khi chúng bị khóa đọc.

Sau đó, MySQL có được một khóa ghi (độc quyền) trên từng bản ghi trong bảng riêng lẻ. Nếu bạn có mệnh đề WHERE trong câu lệnh UPDATE của mình, thì chỉ các bản ghi cụ thể mới bị khóa ghi và một lần nữa, nếu mệnh đề WHERE đã chọn một dải ô, thì bạn sẽ có một dải ô bị khóa.

Bất kỳ bản ghi nào có khóa đọc từ SELECT trước đó sẽ tự động được chuyển sang khóa ghi.

Khóa ghi ngăn các truy vấn khác lấy được khóa đọc hoặc ghi.

Bạn có thể sử dụng Innotop để xem điều này bằng cách chạy nó ở chế độ Khóa, bắt đầu giao dịch, thực hiện truy vấn (nhưng không cam kết) và bạn sẽ thấy các ổ khóa trong Innotop. Ngoài ra, bạn có thể xem chi tiết mà không cần Innotop với SHOW ENGINE INNODB STATUS .

Bế tắc

Truy vấn của bạn dễ bị bế tắc nếu hai phiên bản được chạy cùng một lúc. Nếu truy vấn A có khóa đọc, sau đó truy vấn B nhận khóa đọc, truy vấn A sẽ phải đợi khóa đọc của truy vấn B giải phóng trước khi nó có thể nhận được khóa ghi. Tuy nhiên, truy vấn B sẽ không giải phóng các khóa đọc cho đến khi nó kết thúc và nó sẽ không kết thúc trừ khi nó có thể có được các khóa ghi. Truy vấn A và truy vấn B đang ở trong tình trạng bế tắc và do đó, là bế tắc.

Do đó, bạn có thể muốn thực hiện một khóa bảng rõ ràng, vừa để tránh số lượng lớn các khóa bản ghi (sử dụng bộ nhớ và ảnh hưởng đến hiệu suất), vừa để tránh bế tắc.

Một cách tiếp cận khác là sử dụng CHỌN ... CHO CẬP NHẬT trên CHỌN bên trong của bạn. Điều này bắt đầu với các khóa ghi trên tất cả các hàng thay vì bắt đầu bằng việc đọc và báo cáo chúng.

Bảng có nguồn gốc

Đối với SELECT bên trong, MySQL tạo một bảng tạm thời dẫn xuất. Bảng dẫn xuất là bản sao thực tế không được lập chỉ mục của dữ liệu nằm trong bảng tạm thời được MySQL tạo tự động (trái ngược với bảng tạm thời mà bạn tạo rõ ràng và có thể thêm chỉ mục vào).

Vì MySQL sử dụng bảng dẫn xuất, đó là giá trị cũ tạm thời mà bạn đề cập đến trong câu hỏi của mình. Nói cách khác, không có ma thuật nào ở đây cả. MySQL thực hiện nó giống như bạn làm ở bất kỳ nơi nào khác, với một giá trị tạm thời.

Bạn có thể xem bảng dẫn xuất bằng cách thực hiện GIẢI THÍCH đối với câu lệnh UPDATE của bạn (được hỗ trợ trong MySQL 5.6+).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách tìm THAM GIA LEFT OUTER hoặc RIGHT OUTER JOIN với ORACLE JOIN (+)

  2. Vòng lặp lồng nhau Tham gia vào Oracle 11g

  3. Cân nhắc về hiệu suất cho dữ liệu tạm thời trong Oracle

  4. Các giá trị được phân tách bằng dấu phẩy trong Oracle

  5. Ví dụ về giao dịch tự trị của Oracle