Tôi đã đăng kế hoạch truy vấn của bạn trên giải thích.depesz.com, hãy xem.
Các ước tính của người lập kế hoạch truy vấn ở một số chỗ rất sai. Bạn có chạy ANALYZE
không gần đây?
Đọc các chương trong sổ tay về Thống kê được Người lập kế hoạch và Hằng số Chi phí Người lập kế hoạch sử dụng. Đặc biệt chú ý đến các chương trên random_page_cost
và default_statistics_target
.
Bạn có thể thử:
ALTER TABLE diplomas ALTER COLUMN number SET STATISTICS 1000;
ANALYZE diplomas;
Hoặc thậm chí cao hơn cho bảng có 10 triệu hàng. Nó phụ thuộc vào phân phối dữ liệu và truy vấn thực tế . Thử nghiệm. Mặc định là 100, tối đa là 10000.
Đối với cơ sở dữ liệu có kích thước đó, chỉ 1 hoặc 5 MB của work_mem
nói chung là không đủ. Đọc trang Postgres Wiki về Điều chỉnh Postgres mà @aleroot đã liên kết đến.
Vì truy vấn của bạn cần 430104kB bộ nhớ trên đĩa theo EXPLAIN
đầu ra, bạn phải đặt work_mem
sang thứ gì đó như 500MB trở lên để cho phép sắp xếp trong bộ nhớ. Biểu diễn trong bộ nhớ của dữ liệu cần nhiều không gian hơn so với biểu diễn trên đĩa. Bạn có thể quan tâm đến những gì Tom Lane đã đăng về vấn đề đó gần đây.
Đang tăng work_mem
chỉ một chút, như bạn đã cố gắng, sẽ không giúp được nhiều hoặc thậm chí có thể làm chậm lại. Đặt nó thành cao trên toàn cầu thậm chí có thể gây hại, đặc biệt là với truy cập đồng thời. Nhiều phiên có thể bỏ đói lẫn nhau về tài nguyên. Phân bổ nhiều hơn cho một mục đích sẽ lấy đi bộ nhớ từ mục đích khác nếu tài nguyên bị hạn chế. Thiết lập tốt nhất phụ thuộc vào tình huống hoàn chỉnh.
Để tránh các tác dụng phụ, chỉ đặt nó đủ cao cục bộ trong phiên của bạn và tạm thời cho truy vấn:
SET work_mem = '500MB';
Đặt lại nó về mặc định của bạn sau đó:
RESET work_mem;
Hoặc sử dụng SET LOCAL
để đặt nó chỉ để bắt đầu giao dịch hiện tại.