No sé qué es mejor:responder a mi pregunta o actualizarla... así que elijo responder. Por favor, avíseme si es mejor actualizar
Finalmente encontramos el problema. Desde la versión 3.1, Rails agregó declaraciones preparadas a pedido simple como User.find(id). La versión 4.0 agregó declaraciones preparadas a solicitudes de asociaciones (has_many, pertenecen_a, has_one). Por ejemplo, el siguiente código:
class User
has_many :adresses
end
user.addresses
generar solicitud
SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 1]]
El problema es que Rails solo agrega variables de declaraciones preparadas para claves externas (aquí user_id). Si usa una solicitud de sql personalizada como
user.addresses.where("moved_at < ?", Time.now - 3.month)
no agregará una variable a las declaraciones preparadas para move_at. Por lo tanto, genera declaraciones preparadas cada vez que se llama a la solicitud. Los rieles manejan declaraciones preparadas con un grupo de tamaño máximo de 1000.
Sin embargo, las declaraciones preparadas de postgresql no se comparten entre conexiones, por lo que en una o dos horas cada conexión tiene 1000 declaraciones preparadas. Algunos de ellos son muy grandes. Esto conduce a un consumo de memoria muy alto en el servidor postgreqsl.