Saya tidak tahu apa yang lebih baik:jawab pertanyaan saya atau perbarui ... jadi saya memilih untuk menjawab. Tolong beri tahu saya jika lebih baik memperbarui
Kami akhirnya menemukan masalahnya. Sejak versi 3.1, Rails menambahkan pernyataan yang disiapkan pada permintaan sederhana seperti User.find(id). Versi 4.0, menambahkan pernyataan siap untuk permintaan pada asosiasi (has_many, milik_to, has_one).Misalnya kode berikut:
class User
has_many :adresses
end
user.addresses
buat permintaan
SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 1]]
Masalahnya adalah Rails hanya menambahkan variabel pernyataan yang disiapkan untuk kunci asing (di sini user_id). Jika Anda menggunakan permintaan sql khusus seperti
user.addresses.where("moved_at < ?", Time.now - 3.month)
itu tidak akan menambahkan variabel ke pernyataan yang disiapkan untuk move_at. Jadi itu menghasilkan pernyataan yang disiapkan setiap kali permintaan dipanggil. Rails menangani pernyataan yang disiapkan dengan kumpulan ukuran maksimal 1000.
Namun, pernyataan yang disiapkan postgresql tidak dibagikan di seluruh koneksi, jadi dalam satu atau dua jam setiap koneksi memiliki 1000 pernyataan yang disiapkan. Beberapa dari mereka sangat besar. Hal ini menyebabkan konsumsi memori yang sangat tinggi pada server postgreqsl.