MVCC
Trước hết, nếu "hoạt động bình thường" bao gồm SELECT
các truy vấn, mô hình MVCC sẽ tự động xử lý. UPDATE
không chặn SELECT
và ngược lại. SELECT
chỉ xem dữ liệu đã cam kết (hoặc những gì đã được thực hiện trong cùng một giao dịch), do đó, kết quả của UPDATE
lớn vẫn ẩn đối với các giao dịch khác cho đến khi nó được thực hiện (đã cam kết).
Hiệu suất / độ phồng
Nếu bạn không có các đối tượng khác tham chiếu đến bảng đó,
và bạn không có các thao tác ghi đồng thời (sẽ bị mất!),
và bạn có thể mua một chiếc khóa độc quyền rất ngắn trên bàn,
và tất nhiên bạn có thêm dung lượng đĩa:
Bạn có thể giữ khóa ở mức tối thiểu bằng cách tạo phiên bản cập nhật của bảng trong nền. Đảm bảo rằng nó có mọi thứ để thay thế bản dupe, sau đó bỏ bản gốc và đổi tên bản dupe.
CREATE TABLE tbl_new (LIKE tbl_org INCLUDING CONSTRAINTS);
INSERT INTO tbl_new
SELECT col_a, col_b, array[col] aS col_c
FROM tbl_org;
Tôi đang sử dụng CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS)
, bởi vì (trích dẫn sách hướng dẫn tại đây):
Các ràng buộc not-null luôn được sao chép vào bảng mới.
CHECK
các ràng buộc sẽ chỉ được sao chép nếuINCLUDING CONSTRAINTS
được chỉ định; các loại ràng buộc khác sẽ không bao giờ được sao chép.
Hãy chắc chắn rằng, bảng mới đã sẵn sàng. Sau đó:
DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;
Kết quả trong một khoảng thời gian rất ngắn, trong đó bảng được khóa riêng.
Đây thực sự chỉ là về hiệu suất. Nó tạo ra một bảng mới mà không có bất kỳ khối phồng nào khá nhanh chóng. Nếu bạn có khóa hoặc chế độ xem ngoại lai, bạn vẫn có thể đi theo lộ trình đó, nhưng bạn phải chuẩn bị một tập lệnh để thả và tạo lại các đối tượng này, có khả năng tạo thêm các khóa độc quyền.
Ghi đồng thời
Với các thao tác ghi đồng thời, thực sự tất cả những gì bạn có thể làm là chia bản cập nhật của mình thành nhiều phần. Bạn không thể làm điều đó trong một giao dịch duy nhất, vì khóa chỉ được phát hành khi kết thúc giao dịch.
Bạn có thể tuyển dụng dblink , có thể khởi chạy các giao dịch độc lập trên một cơ sở dữ liệu khác, bao gồm cả chính nó. Bằng cách này, bạn có thể làm tất cả chỉ trong một DO
câu lệnh hoặc một hàm plpgsql với một vòng lặp. Đây là một câu trả lời có liên quan lỏng lẻo với nhiều thông tin hơn về dblink:
- Thả hoặc tạo cơ sở dữ liệu từ quy trình được lưu trữ trong PostgreSQL
Cách tiếp cận của bạn với con trỏ
Con trỏ bên trong hàm sẽ không mua cho bạn bất cứ thứ gì . Bất kỳ chức năng nào cũng được bao gồm trong một giao dịch tự động và tất cả các khóa chỉ được giải phóng khi kết thúc giao dịch. Ngay cả khi bạn đã sử dụng CLOSE cursor
(mà bạn không) nó sẽ chỉ giải phóng một số tài nguyên, nhưng không giải phóng các ổ khóa có được trên bàn. Tôi trích dẫn sách hướng dẫn:
CLOSE
đóng cổng bên dưới một con trỏ đang mở. Điều này có thể được sử dụng để giải phóng tài nguyên trước khi kết thúc giao dịch hoặc để giải phóng biến con trỏ để mở lại.
Bạn sẽ cần chạy tách biệt giao dịch hoặc (ab) sử dụng dblink làm điều đó cho bạn.