Xem điền cơ sở dữ liệu trong sổ tay PostgreSQL, bài viết tuyệt vời như thường lệ của depesz về chủ đề này và câu hỏi SO này.
(Lưu ý rằng câu trả lời này là về việc tải dữ liệu hàng loạt vào một DB hiện có hoặc để tạo một DB mới. Nếu bạn quan tâm, hãy khôi phục hiệu suất DB với pg_restore
hoặc psql
thực thi pg_dump
đầu ra, phần lớn điều này không áp dụng vì pg_dump
và pg_restore
đã làm những việc như tạo trình kích hoạt và chỉ mục sau khi hoàn thành khôi phục lược đồ + dữ liệu) .
Có rất nhiều việc phải làm. Giải pháp lý tưởng sẽ là nhập vào một UNLOGGED
bảng không có chỉ mục, sau đó thay đổi nó thành đã ghi và thêm các chỉ mục. Rất tiếc trong PostgreSQL 9.4 không có hỗ trợ thay đổi bảng từ UNLOGGED
để đăng nhập. 9.5 thêm ALTER TABLE ... SET ĐĂNG NHẬP
để cho phép bạn làm điều này.
Nếu bạn có thể đưa cơ sở dữ liệu của mình ngoại tuyến để nhập hàng loạt, hãy sử dụng pg_bulkload
.
Nếu không:
-
Tắt mọi trình kích hoạt trên bảng
-
Thả các chỉ mục trước khi bắt đầu nhập, tạo lại chúng sau đó. (Cần nhiều ít thời gian hơn để tạo chỉ mục trong một lần vượt qua so với việc thêm dữ liệu tương tự vào đó dần dần và chỉ mục kết quả nhỏ gọn hơn nhiều).
-
Nếu thực hiện nhập trong một giao dịch duy nhất, có thể an toàn để loại bỏ các ràng buộc khóa ngoại, thực hiện nhập và tạo lại các ràng buộc trước khi cam kết. Không làm điều này nếu quá trình nhập được chia thành nhiều giao dịch vì bạn có thể tạo ra dữ liệu không hợp lệ.
-
Nếu có thể, hãy sử dụng
COPY
thay vìINSERT
s -
Nếu bạn không thể sử dụng
COPY
cân nhắc sử dụngINSERT
đa giá trị s nếu thực tế. Bạn dường như đang làm điều này rồi. Đừng cố liệt kê quá nhiều giá trị trong mộtVALUES
duy nhất Tuy nhiên; những giá trị đó phải vừa với bộ nhớ vài lần, vì vậy hãy giữ nó ở mức vài trăm cho mỗi câu lệnh. -
Đưa các lần chèn của bạn vào các giao dịch rõ ràng, thực hiện hàng trăm nghìn hoặc hàng triệu lần chèn cho mỗi giao dịch. Không có giới hạn thực tế AFAIK, nhưng theo lô sẽ cho phép bạn khôi phục lỗi bằng cách đánh dấu thời điểm bắt đầu mỗi lô trong dữ liệu đầu vào của bạn. Một lần nữa, bạn dường như đã làm điều này.
-
Sử dụng
sync_commit =off
và mộtcommit_delay
khổng lồ để giảm chi phí fsync (). Tuy nhiên, điều này sẽ không giúp ích nhiều nếu bạn đã dồn công việc của mình vào các giao dịch lớn. -
INSERT
hoặcCOPY
song song từ một số kết nối. Số lượng bao nhiêu tùy thuộc vào hệ thống con đĩa cứng của bạn; theo nguyên tắc chung, bạn muốn có một kết nối cho mỗi ổ cứng vật lý nếu sử dụng bộ nhớ gắn trực tiếp. -
Đặt
max_wal_size
cao giá trị (checkpoint_searies
trong các phiên bản cũ hơn) và bậtlog_checkpoints
. Xem xét nhật ký PostgreSQL và đảm bảo rằng nó không phàn nàn về các điểm kiểm tra xảy ra quá thường xuyên. -
Nếu và chỉ nếu bạn không ngại mất toàn bộ cụm PostgreSQL của mình (cơ sở dữ liệu của bạn và bất kỳ cụm nào khác trên cùng một cụm) vào tình trạng hỏng nghiêm trọng nếu hệ thống gặp sự cố trong quá trình nhập, bạn có thể dừng Pg, đặt
fsync =off , bắt đầu Pg, thực hiện nhập của bạn, sau đó (quan trọng) dừng Pg và đặt
fsync =on
lần nữa. Xem cấu hình WAL. Không làm điều này nếu đã có bất kỳ dữ liệu nào bạn quan tâm trong bất kỳ cơ sở dữ liệu nào trên bản cài đặt PostgreSQL của bạn. Nếu bạn đặtfsync =off
bạn cũng có thể đặtfull_page_writes =off
; một lần nữa, bạn chỉ cần nhớ bật lại sau khi nhập để ngăn cơ sở dữ liệu bị hỏng và mất dữ liệu. Xem các cài đặt không bền trong hướng dẫn sử dụng Pg.
Bạn cũng nên xem xét điều chỉnh hệ thống của mình:
-
Sử dụng chất lượng tốt SSD để lưu trữ càng nhiều càng tốt. Ổ cứng SSD tốt với bộ nhớ đệm ghi lại được bảo vệ bằng năng lượng và đáng tin cậy giúp tốc độ cam kết nhanh hơn đáng kinh ngạc. Chúng ít có lợi hơn khi bạn làm theo lời khuyên ở trên - điều này làm giảm số lần xả đĩa / số lượng
fsync ()
s - nhưng vẫn có thể là một trợ giúp lớn. Không sử dụng SSD giá rẻ mà không có biện pháp bảo vệ khi mất điện thích hợp trừ khi bạn không quan tâm đến việc lưu giữ dữ liệu của mình. -
Nếu bạn đang sử dụng RAID 5 hoặc RAID 6 để lưu trữ trực tiếp kèm theo, hãy dừng lại ngay bây giờ. Sao lưu dữ liệu của bạn, cấu trúc lại mảng RAID của bạn thành RAID 10 và thử lại. RAID 5/6 là vô vọng đối với hiệu suất ghi hàng loạt - mặc dù bộ điều khiển RAID tốt với bộ nhớ đệm lớn có thể giúp ích.
-
Nếu bạn có tùy chọn sử dụng bộ điều khiển RAID phần cứng với bộ nhớ đệm ghi lại được hỗ trợ bằng pin lớn, điều này thực sự có thể cải thiện hiệu suất ghi cho khối lượng công việc có nhiều cam kết. Sẽ không hữu ích nhiều nếu bạn đang sử dụng cam kết không đồng bộ với commit_delay hoặc nếu bạn đang thực hiện ít giao dịch lớn hơn trong quá trình tải hàng loạt.
-
Nếu có thể, hãy lưu trữ WAL (
pg_wal
hoặcpg_xlog
trong các phiên bản cũ) trên một đĩa / mảng đĩa riêng biệt. Có rất ít điểm trong việc sử dụng một hệ thống tệp riêng biệt trên cùng một đĩa. Mọi người thường chọn sử dụng một cặp RAID1 cho WAL. Một lần nữa, điều này có nhiều tác động hơn đối với các hệ thống có tỷ lệ cam kết cao và nó có ít ảnh hưởng nếu bạn đang sử dụng bảng đã mở khóa làm mục tiêu tải dữ liệu.
Bạn cũng có thể quan tâm đến Tối ưu hóa PostgreSQL để kiểm tra nhanh.