2010-08-09 36 views
9

Tôi có một cấu trúc dữ liệu mà trông như thế này:Làm cách nào để nhập * khối dữ liệu khổng lồ vào PostgreSQL?

Model Place 
    primary key "id" 

    foreign key "parent" -> Place 
    foreign key "neighbor" -> Place (symmetryc) 
    foreign key "belongtos" -> Place (asymmetric) 

    a bunch of scalar fields ... 

tôi có hơn 5 triệu hàng trong bảng mô hình, và tôi cần phải chèn ~ 50 triệu hàng vào mỗi hai bảng chính nước ngoài. Tôi có SQL file mà trông như thế này:

INSERT INTO place_belongtos (from_place_id, to_place_id) VALUES (123, 456); 

và họ sắp 7 Gb mỗi. Vấn đề là, khi tôi làm psql < belongtos.sql, tôi mất khoảng 12 giờ để nhập ~ 4 triệu hàng trên CPU AMD Turion64x2 của tôi. Hệ điều hành là Gentoo ~ amd64, PostgreSQL là phiên bản 8.4, được biên dịch cục bộ. Các dir dữ liệu là một gắn kết gắn kết, nằm trên phân vùng mở rộng thứ hai của tôi (ext4), mà tôi tin rằng không phải là nút cổ chai.

Tôi nghi ngờ mất nhiều thời gian để chèn quan hệ khóa ngoài vì psql kiểm tra các ràng buộc chính cho mỗi hàng, có thể thêm một số chi phí không cần thiết, vì tôi biết chắc chắn rằng dữ liệu hợp lệ. Có cách nào để tăng tốc quá trình nhập, tức là tạm thời vô hiệu hóa kiểm tra ràng buộc không?

+0

có nhưng tôi nghĩ rằng chỉ trong 8.4+ hmm phải tìm kiếm ... – xenoterracide

Trả lời

16
  1. Hãy chắc chắn rằng cả hai ràng buộc khoá ngoại là DEFERRABLE
  2. Sử dụng COPY để tải dữ liệu của bạn
  3. Nếu bạn không thể sử dụng COPY, sử dụng một prepared statement cho INSERT của bạn.
  4. Cài đặt cấu hình Propper cũng sẽ trợ giúp, kiểm tra cài đặt WAL.
+4

+1 cho COPY, tạo sự khác biệt rất lớn đối với DBs. dữ liệu thường xuyên ... – Ryley

+0

Tôi đã sử dụng DEFERRABLE. COPY là thứ tôi đang tìm kiếm, cảm ơn! –

+0

Sử dụng khó chịu là một điều, thực sự sử dụng tùy chọn này là một điều khác: INITIALLY DEFERRED hoặc SET CONSTRAINTS ALL DEFERRED; –

0

Câu trả lời là có ... Depesz wrote an article here on deferrable uniqueness. tiếc là nó có vẻ là một tính năng 9.0.

hmm ... Có thể bài viết đó không áp dụng cho trường hợp của bạn? Dường như chúng tôi đã có thể set constraints to deferred trong một thời gian ... Tôi đoán rằng duy nhất là một tình huống duy nhất (chơi chữ dự định).

+0

Khóa ngoại đã bị trì hoãn trong các phiên bản cũ hơn, không có vấn đề gì. –

+0

Này, học điều gì đó mới mỗi ngày;). – xenoterracide

+0

Bài viết từ Depesz mô tả các ràng buộc * độc nhất * (ví dụ: khóa chính) không bị trì hoãn trước 9.0 ví dụ chạy UPDATE id = id + 1 (trong đó id là cột PK) Ràng buộc FK thông thường có "luôn" bị trì hoãn. Thiết lập ràng buộc để trì hoãn sẽ không ngăn cản việc kiểm tra, nó sẽ chỉ _delay_ việc kiểm tra đến cuối giao dịch (nghĩa là khi cam kết được thực hiện) –

Các vấn đề liên quan