PostgreSQL có tối ưu hóa việc thêm các cột với các DEFAULT không phải NULL không?


9

Khi thêm NOT NULLcác cột có DEFAULTgiá trị - PostgreSQL có tối ưu hóa thao tác này không?

Trong trường hợp bảng có n hàng, một cột bổ sung bảng thay đổi không được tối ưu hóa sẽ mang lại n ghi giá trị mặc định - rõ ràng có thể rất đau đớn. Với việc tối ưu hóa, DB sẽ tạo ngay cột mới, lưu trữ chỉ một bản sao của giá trị mặc định sẽ được trả về khi không tìm thấy giá trị không mặc định nào cho cột đó trong cấu trúc dữ liệu chỉ mục phù hợp.

Ví dụ Oracle 11g có tối ưu hóa như vậy .

Câu trả lời:


15

Không có cơ chế như vậy trong PostgreSQL.

Tuy nhiên, bạn vẫn có thể tránh các tác động quá mức của việc thay đổi bảng như vậy.

Câu lệnh sau có được khóa độc quyền truy cập trên bảng trong suốt thời gian của câu lệnh / giao dịch:

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Câu lệnh này thay đổi danh mục, sau đó viết lại toàn bộ bảng để cột mới chứa giá trị mặc định trong tất cả các hàng. Nếu bảng có nhiều hàng và được truy cập đủ thường xuyên, điều này sẽ gây ra một số vấn đề tạm thời.

Để tránh điều đó, hãy cố gắng giữ khóa độc quyền càng ngắn càng tốt:

ALTER TABLE your_table
    ADD COLUMN new_column integer;
ALTER TABLE your_table
    ALTER COLUMN new_column SET DEFAULT 0;

Vì về cơ bản, đây chỉ là một thay đổi (thực tế là hai) đối với danh mục (không có thay đổi dữ liệu nào xảy ra), nó sẽ hoàn thành khá nhanh. Sau đó tùy thuộc vào nhu cầu và cách sử dụng bảng của bạn, bạn có thể cập nhật cột mới thành mặc định theo một bước hoặc theo đợt và khi hoàn tất, hãy đặt cột thành NOT NULL.

Cập nhật về một điều ước sắp thành hiện thực: PostgreQuery 11 sẽ có tính năng này. Xem https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ để biết thêm.


3

Có, với PostgreSQL 11

Tính năng này là mới và hạ cánh trong Phiên bản 11.

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Trên đây là một lệnh như vậy sẽ bị ảnh hưởng bởi tối ưu hóa này; nhưng, nó nên được cho biết NOT NULLkhông cần thiết. Bất kỳ cột mới nào được thêm với mặc định không null đều được tối ưu hóa ngay bây giờ. Bạn có thể tìm thấy mục trong cam kết này Bạn cũng nên kiểm tra bài viết tuyệt vời này về nó, "Liên kết bị thiếu trong Postgres 11: Tạo cột nhanh với mặc định" .

Pre-PostgreSQL 11 Workaround

Nếu bạn đang cố gắng tránh khóa bàn độc quyền trên bàn, hãy làm theo lời khuyên từ Craig Ringer,

  • Thêm một cột không có DEFAULT
  • ALTERnó để thêm vào DEFAULTsau đó để áp dụng cho các hàng mới được chèn
  • Sau đó, cư cột mới trên hàng hiện tại bằng cách tiến bộ hàng loạt UPDATEs
  • Khi tất cả các hàng có giá trị, bạn thêm NOT NULLràng buộc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.