Làm cách nào để duy trì hiệu suất INSERT cao trên PostgreSQL


9

Tôi đang làm việc trên một dự án phân tích dữ liệu từ các tệp đo lường vào cơ sở dữ liệu Posgres 9.3.5.

Tại lõi là một bảng (được phân chia theo tháng) chứa một hàng cho mỗi điểm đo:

CREATE TABLE "tblReadings2013-10-01"
(
-- Inherited from table "tblReadings_master":  "sessionID" integer NOT NULL,
-- Inherited from table "tblReadings_master":  "fieldSerialID" integer NOT NULL,
-- Inherited from table "tblReadings_master":  "timeStamp" timestamp without time zone NOT NULL,
-- Inherited from table "tblReadings_master":  value double precision NOT NULL,
  CONSTRAINT "tblReadings2013-10-01_readingPK" PRIMARY KEY ("sessionID", "fieldSerialID", "timeStamp"),
  CONSTRAINT "tblReadings2013-10-01_fieldSerialFK" FOREIGN KEY ("fieldSerialID")
      REFERENCES "tblFields" ("fieldSerial") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "tblReadings2013-10-01_sessionFK" FOREIGN KEY ("sessionID")
  REFERENCES "tblSessions" ("sessionID") MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "tblReadings2013-10-01_timeStamp_check" CHECK ("timeStamp" >= '2013-10-01 00:00:00'::timestamp without time zone AND "timeStamp" < '2013-11-01 00:00:00'::timestamp without time zone)
)

Chúng tôi đang trong quá trình điền vào bảng với dữ liệu đã được thu thập. Mỗi tệp đại diện cho một giao dịch khoảng 48.000 điểm và có vài nghìn tệp. Chúng được nhập khẩu bằng cách sử dụng mộtINSERT INTO "tblReadings_master" VALUES (?,?,?,?);

Ban đầu, các tệp nhập với tốc độ hơn 1000 lần chèn / giây nhưng sau một thời gian (một lượng không nhất quán nhưng không bao giờ dài hơn 30 phút hoặc lâu hơn) tốc độ này giảm xuống còn 10-40 lần chèn / giây và quá trình Postgres xử lý CPU. Cách duy nhất để phục hồi tỷ lệ ban đầu là thực hiện chân không đầy đủ và phân tích. Điều này cuối cùng sẽ được lưu trữ khoảng 1.000.000.000 hàng mỗi bảng hàng tháng để việc hút bụi mất một thời gian.

EDIT: Đây là một ví dụ về việc nó chạy một thời gian trên các tệp nhỏ hơn và sau đó sau khi các tệp lớn hơn bắt đầu, nó đã thất bại. Các tệp lớn hơn trông thất thường hơn nhưng tôi nghĩ đó là do giao dịch chỉ được cam kết ở cuối tệp, khoảng 40 giây. CPU và Chèn dấu vết của sự cố

Sẽ có một giao diện người dùng web chọn một số mục nhưng không có cập nhật hoặc xóa và điều này được nhìn thấy mà không có kết nối hoạt động nào khác.

Câu hỏi của tôi là:

  1. Làm thế nào chúng ta có thể biết điều gì gây ra sự chậm chạp / đường ray CPU (cái này có trên Windows)?
  2. Chúng ta có thể làm gì để duy trì hiệu suất ban đầu?

Kích thước giao dịch / tập tin có thể quan trọng. Hiện tại, nó đang chạy qua một loạt các tệp với khoảng 4000 INSERT và đã nhập chúng thành công trong 1 giờ 30 cho đến nay.
jamesmc86

Tôi cũng không phải là chuyên gia của Postgres, nhưng nếu điều này xuất hiện với MySQL, tôi sẽ thử một vài điều: xem liệu việc cam kết theo thời gian có giúp ích gì không; kiểm tra xem có cách nào tốt hơn để tải dữ liệu từ các tệp không (trong MySQL có a LOAD DATA INFILE); có thể sự chậm lại là do dân số / tổ chức chỉ mục sau mỗi lần chèn, xem liệu dữ liệu của bạn có cho phép bạn vô hiệu hóa một số (hoặc tất cả) chỉ mục, INSERTmọi thứ và sau đó kích hoạt lại các chỉ mục; Tôi không nghĩ rằng nó thực sự có thể giúp ích, nhưng khóa bàn có thể là một lựa chọn khác.
chảy nước

"chân không đầy đủ" là mơ hồ. Nó có thể có nghĩa VACUUM FULLtrên một bảng cụ thể hoặc đơn giản - VACUUMtrên toàn bộ cơ sở dữ liệu hoặc VACUUM FULLtrên toàn bộ cơ sở dữ liệu. Dù sao thực tế là nó giúp với hiệu suất là đáng ngờ. VACUUM lấy lại các hàng chết do CẬP NHẬT và XÓA, không cần thiết trong kịch bản chỉ CHỈ.
Daniel Vérité

1
Đó là một VACUUM FULL mà chúng tôi đang làm. Với sự giúp đỡ từ những kẻ trên kênh IRC, có vẻ như vấn đề là do chỉ số bị phân mảnh
jamesmc86

Câu trả lời:


6

Có một vài điều có thể gây ra vấn đề này, nhưng tôi không thể chắc chắn bất kỳ vấn đề nào trong số đó là vấn đề thực sự. Tất cả các khắc phục sự cố liên quan đến việc bật đăng nhập thêm vào cơ sở dữ liệu, sau đó xem liệu các phần chậm có xếp hàng với các thông báo ở đó không. Đảm bảo bạn đặt dấu thời gian trong cài đặt log_line_prefix để có các bản ghi hữu ích để xem xét. Xem phần giới thiệu điều chỉnh của tôi để bắt đầu tại đây: https://wiki.postgresql.org/wiki/Tuning_Your_PostgreQuery_Server

Postgres thực hiện tất cả ghi vào bộ đệm của hệ điều hành, sau đó chúng tiến vào đĩa. Bạn có thể xem bằng cách bật log_checkpoint và đọc tin nhắn. Khi mọi thứ chậm lại, có thể chỉ đơn giản là tất cả các bộ nhớ cache đã đầy, và tất cả các bài viết đều bị kẹt chờ phần I / O chậm nhất. Bạn có thể cải thiện điều này bằng cách thay đổi cài đặt điểm kiểm tra Postgres.

Có một vấn đề nội bộ với cơ sở dữ liệu mà mọi người gặp phải đôi khi trong đó các phần chèn nặng bị kẹt khi chờ khóa trong cơ sở dữ liệu. Bật log_lock_waits để xem bạn có đang đánh nó không.

Đôi khi, tốc độ bạn có thể thực hiện chèn liên tục cao hơn mức bạn có thể duy trì sau khi quy trình tự động hệ thống khởi động. Bật log_autovacuum để xem các sự cố có xảy ra khi xảy ra không.

Chúng tôi biết rằng bộ nhớ lớn trong bộ nhớ cache shared_buffers riêng của cơ sở dữ liệu không hoạt động tốt trên Windows như trên các hệ điều hành khác. Không có nhiều khả năng nhìn thấy những gì sai khi nó xảy ra. Tôi sẽ không cố lưu trữ thứ gì đó đang thực hiện hơn 1000 lần chèn một giây vào cơ sở dữ liệu Windows PostgreQuery. Nó chỉ không phải là một nền tảng tốt cho các bài viết thực sự nặng nề.


0

Tôi không phải là chuyên gia của Postgres nên điều này có thể sai! Khóa chính của bạn có 3 cột, sessionID là trường đầu tiên. Liệu các tập tin có chứa một sự lây lan tốt của dấu thời gian? bạn có thể cân nhắc việc tạo trường đầu tiên trong khóa chính hoặc sử dụng khóa thay thế vì hiện tại trường này khá rộng.

Từ kịch bản của bạn, tôi không nghĩ rằng bạn có một cụm. Khác với SQL Server nhưng tôi nghĩ bạn phải chỉ định theo thứ tự vật lý của bảng trong Postgres bằng lệnh 'Cluster'. Liên kết nói về điều này:

/programming/4796548/about-clustered-index-in-postgres


Postgres không có các chỉ mục được nhóm, vì vậy "khá rộng" cho PK không thực sự là một vấn đề như với SQL Server.
a_horse_with_no_name

Cảm ơn bạn đã trả lời, không có cột nào trong số đó là duy nhất riêng lẻ, đó là lý do tại sao chúng tôi thực hiện theo cách này
jamesmc86
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.