Cách hiệu quả nhất để thêm một cột nối tiếp vào một bảng lớn


10

Là gì nhanh nhất cách để thêm một cột BIGSERIAL vào một bảng rất lớn (~ 3 Bil. Hàng, ~ 174Gb)?

BIÊN TẬP:

  • Tôi muốn cột được tăng giá trị cho các hàng hiện có ( NOT NULL).
  • Tôi đã không đặt fillfactor (có vẻ như là một quyết định tồi khi nhìn lại).
  • Tôi không gặp vấn đề với dung lượng đĩa, chỉ muốn nó nhanh nhất có thể.

Câu trả lời:


12

Có chuyện gì với:

ALTER TABLE foo ADD column bar bigserial;

Sẽ được điền tự động với các giá trị duy nhất (bắt đầu bằng 1).

Nếu bạn muốn một số cho mỗi hàng hiện có, mỗi hàng trong bảng phải được cập nhật . Hay bạn không?

Bảng sẽ được tăng lên gấp đôi kích thước của nó nếu nó không thể sử dụng lại các bộ dữ liệu chết hoặc không gian trống trên các trang dữ liệu. Hiệu suất của hoạt động có thể được hưởng lợi rất nhiều từ FILLFACTORmức thấp hơn 100 hoặc chỉ các bộ dữ liệu chết ngẫu nhiên trải rộng trên bàn. Khác bạn có thể muốn chạy VACUUM FULL ANALYZEsau đó để phục hồi không gian đĩa. Điều này sẽ không được nhanh chóng, mặc dù.

pgstattuple
Bạn có thể quan tâm đến phần mở rộng này. Nó giúp bạn thu thập số liệu thống kê trên bàn của bạn. Để tìm hiểu về bộ dữ liệu chết và không gian trống:

Cài đặt tiện ích mở rộng một lần cho mỗi databae:

CREATE EXTENSION pgstattuple;

Gọi:

SELECT * FROM pgstattuple('tbl');

Thay thế

Nếu bạn có đủ khả năng để tạo một bảng mới, sẽ phá vỡ tùy thuộc vào chế độ xem, khóa ngoại, ...

Tạo một bản sao trống của bảng cũ:

CREATE new_tbl AS
SELECT *
FROM   old_tbl
LIMIT  0;

Thêm cột bigserial:

ALTER new_tbl ADD column bar bigserial;

Dữ liệu INSERT từ bảng cũ, tự động điền vào bigserial:

INSERT INTO new_tbl
SELECT *    --  new column will be filled with default
FROM   old_tbl
ORDER  BY something; -- or don't order if you don't care: faster

Cột bigserial mới bị thiếu trong CHỌN của INSERT và sẽ tự động được điền với giá trị mặc định của nó . Bạn có thể đánh vần tất cả các cột và thêm nextval()vào SELECTdanh sách để có cùng hiệu ứng.

Hãy chắc chắn rằng bạn có tất cả dữ liệu của bạn trong bảng mới.
Thêm chỉ mục, các ràng buộc, kích hoạt bạn đã có trong bảng cũ bây giờ .

DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;

Có thể là khá nhanh hơn một chút về tổng thể. Điều này để lại cho bạn một bảng vani (và chỉ mục) mà không có bất kỳ sự phình to nào.

Bạn cần không gian đĩa trống - xung quanh kích thước của bàn cũ, tùy thuộc vào trạng thái của bàn - như phòng ngọ nguậy. Nhưng bạn có thể cần nhiều như vậy với phương pháp đơn giản đầu tiên vì bảng phình. Một lần nữa, các chi tiết phụ thuộc vào trạng thái của bảng của bạn.


3
Gói thay thế trong một giao dịch duy nhất, sẽ nhanh hơn nhiều. Nó sẽ tránh fsyncs thêm
Frank Heikens
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.