Do mô hình MVCC của Postgres và theo quy tắc của SQL, một UPDATE
phiên bản hàng mới viết cho mỗi hàng không được loại trừ trong WHERE
mệnh đề.
Điều này có tác động ít nhiều đến hiệu suất, trực tiếp và gián tiếp. "Cập nhật trống" có cùng chi phí cho mỗi hàng như mọi bản cập nhật khác. Chúng kích hoạt kích hoạt (nếu có) như bất kỳ bản cập nhật nào khác, chúng phải được ghi nhật ký WAL và chúng tạo ra các hàng chết làm đầy bảng và gây ra nhiều công việc hơn cho VACUUM
sau này như bất kỳ bản cập nhật nào khác.
Các mục chỉ mục và các cột TOASTed trong đó không có cột nào liên quan được thay đổi có thể giữ nguyên, nhưng điều đó đúng với bất kỳ hàng cập nhật nào. Liên quan:
Hầu như luôn luôn là một ý tưởng tốt để loại trừ các cập nhật trống như vậy (khi có cơ hội thực tế nó có thể xảy ra). Bạn đã không cung cấp một định nghĩa bảng trong câu hỏi của bạn (luôn luôn là một ý tưởng tốt). Chúng ta phải giả sử first_name
có thể là NULL (điều này sẽ không gây ngạc nhiên cho "tên gọi"), do đó truy vấn phải sử dụng so sánh NULL an toàn :
UPDATE users
SET first_name = 'Michael'
WHERE id = 123
AND first_name IS DISTINCT FROM 'Michael';
Nếu first_name IS NULL
trước khi cập nhật, một bài kiểm tra chỉ first_name <> 'Michael'
đánh giá NULL và như vậy sẽ loại trừ hàng khỏi bản cập nhật. Lỗi lén lút. Tuy nhiên, nếu cột được xác địnhNOT NULL
, hãy sử dụng kiểm tra đẳng thức đơn giản, vì nó rẻ hơn một chút.
Liên quan: