Tôi không biết điều gì tốt hơn:trả lời câu hỏi của tôi hoặc cập nhật nó ... vì vậy tôi chọn trả lời. Vui lòng cho tôi biết nếu cập nhật tốt hơn
Cuối cùng chúng tôi cũng tìm ra vấn đề. Kể từ phiên bản 3.1, Rails đã thêm các câu lệnh được chuẩn bị sẵn theo yêu cầu đơn giản như User.find (id). Phiên bản 4.0, đã thêm các câu lệnh được chuẩn bị sẵn vào các yêu cầu về liên kết (has_many, Thuộc_to, has_one). Đối với mã sau đây:
class User
has_many :adresses
end
user.addresses
tạo yêu cầu
SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 1]]
Vấn đề là Rails chỉ thêm các biến câu lệnh đã chuẩn bị sẵn cho các khóa ngoại (ở đây là user_id). Nếu bạn sử dụng yêu cầu sql tùy chỉnh như
user.addresses.where("moved_at < ?", Time.now - 3.month)
nó sẽ không thêm một biến vào các câu lệnh đã chuẩn bị cho move_at. Vì vậy, nó tạo ra một câu lệnh chuẩn bị mỗi khi yêu cầu được gọi. Rails xử lý các câu lệnh đã chuẩn bị với một nhóm có kích thước tối đa là 1000.
Tuy nhiên, các câu lệnh chuẩn bị sau postgresql không được chia sẻ trên toàn bộ kết nối, vì vậy trong một hoặc hai giờ mỗi kết nối có 1000 câu lệnh được chuẩn bị sẵn. Một số trong số chúng rất lớn. Điều này dẫn đến tiêu thụ bộ nhớ rất cao trên máy chủ postgreqsl.