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ó 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:
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
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_tbl
trong đườ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');
prefetch
phá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á.
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.columns
trong 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.
SELECT * FROM schema.table
và thấy nó tải toàn bộ bảng 60GiB vào bộ đệm bộ đệm 100GiB PostgreQuery của tôi.
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.
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.
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.