2011-11-30 23 views
5

Tôi có một vấn đề thông lượng với chuỗi DELETE/INSERT trên PostgreSQL 9.0. Tôi đang tìm kiếm ý tưởng để cải thiện tình hình.PostgreSQL DELETE/INSERT thông lượng vấn đề

Trên phần cứng có sẵn cho chúng tôi, tôi có thể INSERT hàng mới vào cơ sở dữ liệu với tốc độ ổn định 3000/s (đồng đều trên 10 bảng) ngoài hàng 1m trong mỗi bảng mà tôi thường kiểm tra. Tuy nhiên, nếu tôi chuyển sang chế độ mà chúng tôi XÓA một hàng và chèn lại nó bằng các dữ liệu khác nhau, hiệu suất sẽ giảm hơn một bậc độ lớn đến 250 hàng/s (một lần nữa, đồng đều trên 10 bảng).

Không có ràng buộc nào đối với bất kỳ bảng nào. Có 2 cột được lập chỉ mục trong mỗi bảng với tổng kích thước chỉ mục (ở 1m hàng trên mỗi bảng) là 1GB, thoải mái trong shared_buffers (2GB). Tổng kích thước dữ liệu (với 1m hàng trên mỗi bảng) là 12GB, thấp hơn nhiều so với tổng số RAM hệ thống. Đây là một cơ sở dữ liệu bóng nơi chúng tôi có thể đủ khả năng để xây dựng lại trong trường hợp khẩn cấp, vì vậy chúng tôi chạy với fsync tắt.

Có vẻ như khi chúng tôi đang ở chế độ phổ biến, chúng tôi hưởng lợi từ thời gian tìm kiếm đĩa rất thấp vì dữ liệu đang được nối thêm. Tuy nhiên, khi chúng tôi chuyển sang chế độ cập nhật, có rất nhiều tìm kiếm đang diễn ra (để xóa các hàng cũ có lẽ). Đĩa ngẫu nhiên tìm kiếm chi phí ~ 8ms (= ~ 125 mỗi giây). Có cách nào (không thay đổi phần cứng) mà chúng tôi có thể cải thiện đáng kể hiệu suất của các hoạt động UPDATE/tái INSERT không?

EDIT1: Tôi đang thực hiện các thử nghiệm hoàn thiện trên hai nền tảng phần cứng đặc biệt khác nhau. Những con số tôi đã trích dẫn trước đó là từ nền tảng đặc tả cao hơn. Tôi vừa hoàn thành chạy thử nghiệm trên nền tảng spec thấp hơn. Trong bài kiểm tra này, tôi chèn các hàng mới càng nhanh càng tốt, ghi lại tốc độ chèn mỗi 10 giây, cho đến khi tôi chèn 1 triệu hàng. Tại thời điểm này, tập lệnh thử nghiệm của tôi chuyển sang cập nhật các hàng ngẫu nhiên.

Perf results graph

Biểu đồ này cho thấy tốc độ cập nhật đo là ~ 150 cập nhật cho tất cả 10 bảng/giây trong dân số và tốc độ cập nhật là < 10 bản cập nhật cho tất cả 10 bảng/giây.

@wildplasser - Máy là một máy thực, không phải máy ảo. Tất cả 10 bảng đều có lược đồ sau đây.

CREATE TABLE objecti_servicea_item1 
(
    iss_scs_id text, 
    iss_generation bigint, 
    boolattr1 boolean, 
    boolattr2 boolean, 
    boolattr3 boolean, 
    boolattr4 boolean, 
    boolattr5 boolean, 
    boolattr6 boolean, 
    boolattr7 boolean, 
    boolattr8 boolean, 
    boolattr9 boolean, 
    boolattr10 boolean, 
    boolattr11 boolean, 
    boolattr12 boolean, 
    boolattr13 boolean, 
    boolattr14 boolean, 
    boolattr15 boolean, 
    boolattr16 boolean, 
    boolattr17 boolean, 
    intattr1 bigint, 
    intattr2 bigint, 
    intattr3 bigint, 
    intattr4 bigint, 
    intattr5 bigint, 
    intattr6 bigint, 
    intattr7 bigint, 
    intattr8 bigint, 
    intattr9 bigint, 
    intattr10 bigint, 
    intattr11 bigint, 
    intattr12 bigint, 
    intattr13 bigint, 
    intattr14 bigint, 
    intattr15 bigint, 
    intattr16 bigint, 
    intattr17 bigint, 
    strattr1 text[], 
    strattr2 text[], 
    strattr3 text[], 
    strattr4 text[], 
    strattr5 text[], 
    strattr6 text[], 
    strattr7 text[], 
    strattr8 text[], 
    strattr9 text[], 
    strattr10 text[], 
    strattr11 text[], 
    strattr12 text[], 
    strattr13 text[], 
    strattr14 text[], 
    strattr15 text[], 
    strattr16 text[], 
    strattr17 text[] 
) 
WITH (
    OIDS=FALSE 
); 
CREATE INDEX objecti_servicea_item1_idx_iss_generation 
    ON objecti_servicea_item1 
    USING btree 
    (iss_generation); 
CREATE INDEX objecti_servicea_item1_idx_iss_scs_id 
    ON objecti_servicea_item1 
    USING btree 
    (iss_scs_id); 

"Cập nhật" đang được thực hiện liên quan đến SQL sau cho mỗi trong số 10 bảng.

DELETE FROM ObjectI_ServiceA_Item1 WHERE iss_scs_id = 'ObjUID39' 
INSERT INTO ObjectI_ServiceA_Item1 
VALUES ('ObjUID39', '2', '0', NULL, '0' 
, NULL, NULL, NULL, '1', '1', NULL, '0' 
, NULL, NULL, NULL, NULL, '0', '1', '1' 
, '-70131725335162304', NULL, NULL, '-5241412302283462832' 
, NULL, '310555201689715409', '575266664603129486' 
, NULL, NULL, NULL, NULL, NULL, NULL 
, '-8898556182251816700', NULL, '3325820251460628173' 
, '-3434461681822953613' 
, NULL 
, E'{pvmo2mt7dma37roqpuqjeu4p8b,"uo1kjt1b3eu9g5vlf0d02l6iaq\\\\\\",",45kfns1j80gc7fri0dm29hnrjo}' 
, NULL, NULL 
, E'{omjv460do8cb7abn8t3eg5b6ki,"a7hrlninbk1rmu6h3rd4787l7f\\\\\\",",24n3ipfua5spma2vrj2aji98g3}' 
, NULL 
, E'{1821v2n2ermm4jujrucu5tekmm,"ukgst224964uhthkhjj9v189ft\\\\\\",",6dfsaniq9mftvbdr8g1sr8e6as}' 
, E'{c2a9gvf0fnd38m8vprlhkp2n74,"ts86vbat12lfr0d7l4tc29k9uk\\\\\\",",32b5j9r5evmrie4h21hi10dpot}' 
, E'{18pve4cmcbrjiom9bpvoo1l4n0,"hrqcsane6r0n7u2oj79bj605rh\\\\\\",",32q5n18q3qbkuit605fv47270o}' 
, E'{l3bf96shrpnnqgt35m7574t5n4,"cpol4k8296hbdqc9kac79oj0ua\\\\\\",",eqioulmb7vav10lbnc5jg752df}' 
, E'{5fai108h163hpjcv0ofgfi7c28,"ci958009ddak3li7bp37slcs8i\\\\\\",",2itstj01tkprlul8f530uhs6s2}' 
, E'{ueqfkdold8vc84jllr4b2cakt5,"t5vbea4r7tva091pa8j6886t60\\\\\\",",ul82aovhil1lpd290s14vd0p3i}' 
, NULL, NULL, NULL, NULL, NULL) 

Lưu ý rằng trong giai đoạn đầu tiên của thử nghiệm perf, lệnh DELETE sẽ không làm gì cả.

@Frank Heikens - Trong thử nghiệm perf mà tôi đang chạy các bản cập nhật đang được thực hiện từ 10 chủ đề. Tuy nhiên, các bản cập nhật được gán cho các luồng theo cách đảm bảo rằng nhiều bản cập nhật cho cùng một hàng luôn được xử lý bởi cùng một luồng.

+0

Đây có phải là máy ảo hoặc máy thực không? Ngoài ra, vui lòng thêm (một đoạn) định nghĩa bảng && truy vấn và kế hoạch truy vấn kết quả cho câu hỏi. – wildplasser

+0

Bạn đã kiểm tra ổ khóa chưa? Nhiều quy trình có thể cố gắng xóa cùng một bản ghi. –

+0

Tôi đã chỉnh sửa bài đăng của mình để trả lời nhận xét của bạn. – mchr

Trả lời

3

Biểu trưng dữ liệu này không phải là một vẻ đẹp, DELETE - INSERT. Có gì sai với một UPDATE? Nếu iss_generation và iss_scs_id không thay đổi trong UPDATE, cơ sở dữ liệu có thể thực hiện HOT update (Heap Overflow Tuple) để tăng hiệu suất. UPDATE cũng sẽ được hưởng lợi từ một fillfactor thấp hơn.

Khi bạn thực hiện DELETE bản ghi, bản ghi đó có thể ở khối khác với nơi INSERT sẽ đi. Sử dụng một fillfactor thấp hơn và sử dụng UPDATE, có thể cung cấp cho cơ sở dữ liệu tùy chọn DELETE và INSERT bản ghi được cập nhật trong cùng một khối trên đĩa. Điều này sẽ dẫn đến I/O ít ngẫu nhiên hơn.Khi HOT có thể được sử dụng, mọi thứ trở nên tốt hơn vì không cần phải cập nhật các chỉ mục.

1

Không chắc chắn, nhưng có thể thay đổi trình điền lấp sẽ giúp ích?

+0

Cảm ơn đề xuất - Tôi sẽ xem xét điều này. – mchr

0

Chúng tôi đã thành công với việc xóa/sao chép từ csv trong bộ nhớ.

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