PostgreSQL: Buộc dữ liệu vào bộ nhớ


32

Có một cách có hệ thống để buộc PostgreSQL tải một bảng cụ thể vào bộ nhớ, hoặc ít nhất là đọc nó từ đĩa để nó sẽ được hệ thống lưu vào bộ nhớ cache?

Câu trả lời:


25

Bạn có thể được xen kẽ vào một trong các chủ đề danh sách gửi thư , đó là câu trả lời của Tom Lane (nhà phát triển cốt lõi):

[..] Nhưng ý kiến ​​của tôi là những người nghĩ rằng họ thông minh hơn thuật toán bộ nhớ đệm LRU thường bị nhầm lẫn. Nếu bảng được sử dụng nhiều, nó sẽ nằm trong bộ nhớ tốt. Nếu nó không đủ mạnh để sử dụng trong bộ nhớ theo thuật toán LRU, có lẽ không gian bộ nhớ thực sự nên dành cho thứ khác. [..]

Bạn cũng có thể được xen vào câu hỏi SO: https://stackoverflow.com/questions/486154/postgresql-t tạm-tables và có thể phù hợp hơn https://stackoverflow.com/questions/407006/need-to-load-the -whole-postgresql-cơ sở dữ liệu-vào-ram


1
+1 Ý tưởng tương tự cũng áp dụng cho các RDBMS khác.
gbn

25
Có và không. Chúng tôi khóa một số bảng trong bộ nhớ của Oracle vì chúng tôi biết rằng chúng có thể không được sử dụng thường xuyên, nhưng trong tình huống chúng được sử dụng, độ trễ sẽ là một kẻ giết người. Một DB phải luôn luôn đưa ra lời nói cuối cùng của DBA (một ví dụ khác là gợi ý trình tối ưu hóa truy vấn).
Gaius

35

Postgres 9.4 cuối cùng đã thêm một tiện ích mở rộng để tải trước dữ liệu từ các mối quan hệ vào bộ đệm bộ đệm của hệ điều hành hoặc cơ sở dữ liệu (theo lựa chọn của bạn):

pg_prewarm

Điều này cho phép đạt được hiệu suất hoạt động đầy đủ nhanh hơn.

Chạy một lần trong cơ sở dữ liệu của bạn (hướng dẫn chi tiết tại đây ):

CREATE EXTENSION pg_prewarm;

Sau đó, thật đơn giản để tải trước bất kỳ mối quan hệ nhất định. Ví dụ cơ bản:

SELECT pg_prewarm('my_tbl');

Tìm bảng đầu tiên có tên my_tbltrong đường dẫn tìm kiếm và tải nó vào bộ đệm bộ đệm Postgres

Hoặc là:

SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');

prefetchphát hành các yêu cầu tìm nạp trước không đồng bộ cho hệ điều hành, nếu điều này được hỗ trợ hoặc ném lỗi khác. read đọc phạm vi yêu cầu của các khối; Không giống như prefetch, điều này là đồng bộ và được hỗ trợ trên tất cả các nền tảng và bản dựng, nhưng có thể chậm hơn. bufferđọc phạm vi khối được yêu cầu vào bộ đệm bộ đệm cơ sở dữ liệu.

Mặc định là buffer, có tác động lớn nhất (chi phí cao hơn, hiệu quả tốt nhất).

Đọc hướng dẫn để biết thêm chi tiết , báo giá là từ đó.
Depesz viết blog về nó, quá.


4

Trong trường hợp chung nếu bạn có đủ RAM, bạn thường có thể tin tưởng vào dịch vụ cơ sở dữ liệu để thực hiện tốt việc giữ những thứ bạn thường xuyên sử dụng trong RAM. Một số hệ thống cho phép bạn gợi ý rằng bảng phải luôn được giữ trong RAM (rất hữu ích cho các bảng nhỏ không được sử dụng thường xuyên nhưng khi chúng được sử dụng, điều quan trọng là chúng phải phản hồi càng nhanh càng tốt) nhưng nếu pssql có gợi ý bảng như vậy bạn cần phải rất cẩn thận về việc sử dụng chúng vì bạn đang giảm dung lượng bộ nhớ có sẵn để lưu vào bộ nhớ cache bất cứ thứ gì khác để bạn có thể làm chậm toàn bộ ứng dụng của mình.

Nếu bạn đang tìm cách khởi động bộ đệm trang của cơ sở dữ liệu khi khởi động (ví dụ sau khi khởi động lại hoặc hoạt động bảo trì khác khiến DB quên mọi thứ được lưu trong bộ nhớ cache), hãy viết một tập lệnh thực hiện như sau:

SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>

(bước cuối cùng được lặp lại cho từng chỉ mục hoặc khóa học và cẩn thận để có các trường trong mệnh đề ORDER BY theo đúng thứ tự)

Sau khi chạy ở trên, mọi trang dữ liệu và chỉ mục nên được đọc và do đó sẽ nằm trong bộ đệm của trang RAM (ít nhất là trong thời gian này). Chúng tôi có các tập lệnh như thế này cho cơ sở dữ liệu ứng dụng của chúng tôi, được chạy sau khi khởi động lại để những người dùng đầu tiên đăng nhập vào hệ thống sau đó không gặp phải phản ứng chậm hơn. Bạn nên viết tay bất kỳ tập lệnh nào như vậy, thay vì quét các bảng định nghĩa db (như sys.objects/ sys.indexes/ sys.columnstrong MSSQL), sau đó bạn có thể quét có chọn lọc các chỉ mục được sử dụng phổ biến nhất thay vì quét mọi thứ sẽ mất nhiều thời gian hơn.


3
Điều này sẽ không hoạt động, ít nhất là trên PostgreSQL. Một bộ đệm vòng nhỏ (256KB) được phân bổ từ các bộ đệm chia sẻ để quét tuần tự để ngăn chặn toàn bộ bộ đệm bộ đệm được sử dụng. Xem github.com/postgres/postgres/blob/master/src/backend/st Storage / khăn để biết chi tiết. Bạn có thể xác minh điều này bằng cách thực hiện CHỌN * từ một bảng lớn sau đó xem bảng pg_buffercache (từ tiện ích mở rộng pg_buffercache).
hbn

@hbn xin chào, nhưng anh chàng đồng nghiệp trong chủ đề lưu này nói rằng nó hoạt động - dba.stackexchange.com/a/36165/55752
scythargon

@scythargon nó có thể kết thúc trong bộ đệm của hệ điều hành, nó sẽ không nhận được nó trong bộ đệm bộ đệm PostgreQuery. Hãy thử những gì tôi đề xuất ở trên nếu bạn không tin tôi.
hbn

Trong Postgres 9.5, tôi đã thử SELECT * FROM schema.tablevà thấy nó tải toàn bộ bảng 60GiB vào bộ đệm bộ đệm 100GiB PostgreQuery của tôi.
sudo

1

Tôi gặp vấn đề tương tự:
Sau khi khởi động lại dịch vụ máy chủ và tất cả dữ liệu được rút tiền, nhiều truy vấn được gọi lần đầu tiên thực sự rất chậm, do sự phức tạp cụ thể của các truy vấn, cho đến khi tất cả các chỉ mục và dữ liệu cần thiết đều được đổi thành tiền mặt. điều đó có nghĩa là, ví dụ người dùng phải nhấn một lần mỗi "mục" (thời gian thực hiện 1-3 giây) và dữ liệu liên quan từ 50 triệu hàng, vì vậy người dùng sẽ không gặp phải bất kỳ sự chậm trễ không mong muốn nào nữa. Phải mất 3 giờ đầu tiên để người dùng gặp phải tình trạng treo máy gây phiền nhiễu, cho đến khi hầu hết dữ liệu được sử dụng đều được thanh toán bằng tiền mặt và các chương trình đang hủy hoại hiệu suất sản xuất, kết thúc ngay cả sau đó, 2 ngày một vài lần chậm trễ đột ngột, khi nhấn vào dữ liệu truy cập lần đầu ít hơn ... , cho dữ liệu thống kê, vv

Để giải quyết điều này, đã viết một tập lệnh python nhỏ thực hiện các lựa chọn trên các bảng được sử dụng nặng nhất với các chỉ mục lớn. Phải mất 15 phút để chạy, và không có sự chậm trễ hiệu suất.


0

Hmmm, có thể lệnh COPY sẽ giúp. Chỉ cần thực hiện COPY để stdout và đọc từ nó. Có thể làm điều đó bằng cách sử dụng pg_dump:

pg_dump -U <user> -t <table> <database> > /dev/null

Cách khác là tìm tất cả các tập tin bảng và chạy cat <files> > /dev/null.

Dưới đây là ví dụ về cách lấy tên tệp bảng:

# SELECT oid, datname FROM pg_database ;
  oid  |  datname  
-------+-----------                                                                                                                                          
<...>
 16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
  oid  | relname 
-------+---------
 24576 | fn
(1 row)
-- oid of our table is 24576

vì vậy, (các) tệp của bảng là / path / to / pssql / data / base / 16384/24576 *

Bạn cũng muốn đọc các chỉ mục và các bảng bánh mì nướng, hãy lấy các ô của chúng theo cùng một cách.

BTW, tại sao bạn cần nó? Tôi tin rằng postgresql và OS đủ thông minh để lưu trữ dữ liệu nóng nhất và duy trì tốt. hiệu quả bộ nhớ cache.


0

Tôi sử dụng RamDrive từ QSoft, được đánh giá là ramdisk nhanh nhất cho Windows. Tôi vừa mới sử dụng

initdb -D e:\data

Trong đó e: \ là nơi của RamDisk.


5
PG trên Windows là một lựa chọn khá dũng cảm cho một trang web sản xuất vì nó chậm hơn Windows so với * nix (không phụ thuộc vào RAM).
DrColossos
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.