Problema grave de rendimiento en los pedidos de odoo v.10c

1,466 views
Skip to first unread message

Josean Soroa - LANDOO

unread,
Feb 21, 2017, 7:17:58 AM2/21/17
to Usuarios Odoo / OpenERP en España
Hola a todos.
Tenemos un problema grave con el rendimiento del odoo v.10c de un cliente.
Agradeceríamos mucho cualquier idea que nos ayude a resolverlo.

Tienen presupuestos de venta de entre 300 y 500 líneas que tardan cerca de 1 minuto en duplicar y ya hay algún pedido que da timeout al validarlo. El facturarlos es igual de lento y en algunos casos falla con timeout.
Los problemas de velocidad se están acentuando a medida que van incorporando datos reales y el volumen de cada pedido va subiendo.
Incrementar el timeout estándar de 60 sg no soluciona gran cosa porque validar un pedido en 5-10 minutos (lo que tarda si no falla) no es operativo.
Hemos revisado la configuración del servidor y está optimizado (workers, etc). Incluso temporalmente lo hemos pasado de 2 cores y 8 RAM a 8 cores y 16RAM y tarda casi mismo.
Creemos que es un problema de rendimiento de odoo, al menos con la configuración de datos que usamos: productos consumibles, variantes, tarifa de precios por cliente y fórmulas. 
El total de datos del sistema es bajo, acaban de empezar. Unos 300 productos con un total de 1800 variantes, unos 200 pedidos, unos 100 clientes, 1 compañía, etc.
Con todo esto, creemos que el problema está en el número de líneas del pedido. 

Hemos pasado los productos a tipo servicio y el sistema mejora mucho, con lo que hemos resuelto la urgencia. De todos modos, a medio plazo ellos u otro cliente necesitará almacén, con lo que no es una solución definitiva.
Alguna idea? Muchas gracias de antemano.

Josean Soroa

Pedro Manuel Baeza Romero

unread,
Feb 21, 2017, 7:21:21 AM2/21/17
to Usuarios Odoo / OpenERP en España
Eso tarda lo que tarda, sin más. Hay muchas operaciones cuando hay almacén de por medio, y más cuando hay tantas líneas. Siempre se puede mirar de optimizar código, estructuras, etc, pero eso es algo de Odoo. Lo que tienes que hacer es aumentar el timeout, que veo que es ridículo lo que le habéis puesto y va a saltar en cuanto tengáis algún informe medianamente grande.

Un saludo.

--
Has recibido este mensaje porque estás suscrito al grupo "Usuarios Odoo / OpenERP en España" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a openerp-spain-users+unsub...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Pedro Rodríguez (Otherway Creatives)

unread,
Feb 21, 2017, 4:33:02 PM2/21/17
to Usuarios Odoo / OpenERP en España
Se mejora bastante el rendimiento teniendo Postgres en una máquina distinta a la de Odoo y montándolo sobre discos SSD, sobre todo esto último ya que Odoo hace mucho "random access" a los datos y en eso los SSD son especialmente buenos (parece que cientos de veces más rápidos que los HDD). También ayuda bastante tener Postgres bien "afinado" en la configuración, ahí hay muchos factores que afectan, desde el hardware que tengas hasta el número de conexiones, pero merece la pena trastear con la configuración porque afecta bastante al rendimiento.

Borja López Soilán

unread,
Feb 22, 2017, 3:00:52 AM2/22/17
to Usuarios Odoo / OpenERP en España
Yo os recomendaría realizar la depuración de consultas lentas en Postgres, a ver si hay suerte y se debe a que no tenéis índices optimizados para vuestra casuística.


En el archivo de configuración de PostgreSQL, podéis activar que registre las consultas más lentas que un tiempo (ms) dado, tal que así:

log_min_duration_statement = 200

De esa forma si hay alguna consulta que está tardando mucho aparecerá en los logs.

Posteriormente podéis usar EXPLAIN (o EXPLAIN ANALYZE) en el cliente de Postgres para ver cómo está realizando la consulta e intentar averiguar por qué tarda tanto.
Muy probablemente podáis mejorar mucho el rendimiento añadiendo algún índice concreto (o creando un índice más compacto) que la mayoría de las instalaciones de Odoo no necesitan, pero la vuestra por tener tantas líneas por pedido sí.


Como ejemplo de lo que se puede lograr con un simple índice bien escogido, esto es una consulta para saber el número total de clientes activos en una base de datos con 20 millones de clientes:

test01=> explain analyze SELECT count(1) FROM "res_partner" WHERE ((("res_partner"."active" = true)  AND  ("res_partner"."customer" = true))  AND  "res_partner"."parent_id" IS NULL );
                                                            QUERY PLAN                                                              
 
-----------------------------------------------------------------------------------------------------------------------------------
 
Aggregate  (cost=1116553.35..1116553.36 rows=1 width=0) (actual time=100658.285..100658.286 rows=1 loops=1)
   
->  Seq Scan on res_partner  (cost=0.00..1066550.88 rows=20000988 width=0) (actual time=0.008..96363.068 rows=20000915 loops=1)
         
Filter: (active AND customer AND (parent_id IS NULL))
         
Rows Removed by Filter: 74
 
Total runtime: 100658.418 ms
(5 rows)

Como véis tarda 100 segundos en hacer el cálculo.

Y creando un simple índice:

test01=> CREATE INDEX partner_customer_menu_index ON res_partner (active, customer, parent_id, company_id);
CREATE INDEX
test01
=> explain analyze SELECT count(1) FROM "res_partner" WHERE ((("res_partner"."active" = true)  AND  ("res_partner"."customer" = true))  AND  "res_partner"."parent_id" IS NULL );
                                                                                QUERY PLAN                                                                                
 
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
Aggregate  (cost=808085.26..808085.27 rows=1 width=0) (actual time=10868.048..10868.049 rows=1 loops=1)
   
->  Index Only Scan using partner_customer_menu_index on res_partner  (cost=0.56..758082.79 rows=20000988 width=0) (actual time=0.059..6959.573 rows=20000915 loops=1)
         
Index Cond: ((active = true) AND (customer = true) AND (parent_id IS NULL))
         
Filter: (active AND customer)
         
Heap Fetches: 0
 
Total runtime: 10868.095 ms
(6 rows)

La misma consulta, al usar el índice pasa a tardar 10 segundos (recordemos, 20 millones de clientes), la décima parte.

En algún OS Commerce bastante grande (tiempo ha) conseguí reducir consultas de 5 minutos a 10 segundos usando esta 'magia' :)

Pedro Manuel Baeza Romero

unread,
Feb 22, 2017, 3:35:52 AM2/22/17
to Usuarios Odoo / OpenERP en España
No quería yo entrar mucho en tema de optimización hardware porque el problema es que decía que le saltaba el timeout, pero ciertamente siempre se puede optar por mejorar la máquina.

En cuanto a optimización Postgres, yo siempre tengo el pg_activity a mano para examinar consultas largas o waits, aunque se agradece ese otro truco, Borja! De todas formas, en la confirmación de pedidos de venta no hay consultas largas como tal, si no muchas consultas diferentes (a procurement.order, stock.move, sale.order.line...), y no veo fácil una optimización a ese nivel, aunque es cierto que no me he metido de lleno a ello. Si alguien lo hace, puede compartir sus experiencias. En https://github.com/OCA/server-tools/pull/736 se está añadiendo la posibilidad de crear índices desde interfaz.

Un saludo.

--

José Antonio Cuello

unread,
Feb 22, 2017, 3:43:10 AM2/22/17
to openerp-s...@googlegroups.com
Hola, gran apunte. Sólo añadiría que al ser los índices un árbol de nodos, debería mejorar el rendimiento si ponemos los campos de mayor variación los primeros en la definición del indice, así en la primera pasada se eliminan el mayor número de nodos por lo que la tabla pasa de 20 millones a unos pocos miles.

Un saludo

El 22 de febrero de 2017, 9:00, Borja López Soilán <borjalop...@gmail.com> escribió:

--

Josean Soroa

unread,
Feb 22, 2017, 7:49:54 AM2/22/17
to openerp-s...@googlegroups.com
Hola, muchas gracias a todos por las ideas.

Pedro, hemos subido el timeout, pero da lo que da.
Pedro, ya usamos SSD aunque todo en 1 máquina VPS. Ahí se podría mejorar con un dedicado, pero no creo que gran cosa.

Borja, vamos a investigar el tema de la optimización de índices, puede ser un buen camino.
Aún así, en nuestro caso concreto, en las pruebas que hemos hecho las tareas más lentas vemos que consumen bastante más CPU en python que en postgresql. Concretamente:
Duplicar pedido de 400 lineas: entre 4 y 15% de CPU en postgresql, el resto hasta 100% python
Facturar pedido de 400 lineas: entre 28 y 36% de CPU en postgresql, el resto python
Confirmar factura de 400 lineas: entre 14 y 33% de CPU en postgresql, el resto python
Si les damos un promedio del 30% de la CPU y mejoramos el trabajo de postgresql dividiendo los tiempos entre 10 (caso real de Borja), aún así estaríamos reduciendo un 27% del proceso global, no?
Alguien me podría confirmar este punto?
Si es así, no está mal, pero no creo que sea suficiente. Estamos hablando de que confirmar un pedido ahora tarde 6 minutos y luego (6-27%) tarde 4min23sg. 
El problema parece que sigue estando en el codigo odoo (proceso python).

Seguiremos investigando y gracias de nuevo.

Josean Soroa

Borja López Soilán

unread,
Feb 22, 2017, 8:16:46 AM2/22/17
to openerp-s...@googlegroups.com

Si el problema está del lado del código Python entonces lo que necesitáis es usar un perfilador de Python para ver donde está perdiendo más tiempo.


Hace tiempo había creado un perfilador específico para OpenERP 6, que analizaba las operaciones del ORM que quizá podríais aprovechar...

Pero probablemente con el cProfile de Python y un poco de maña os baste para ver si hay algún método donde se pierda la mayor parte del tiempo de CPU (bien por lento, bien porque se llama mucho).


Un saludo :)


El 22/02/17 a las 13:49, Josean Soroa escribió:
--
Has recibido este mensaje porque estás suscrito a un tema del grupo "Usuarios Odoo / OpenERP en España" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/openerp-spain-users/KCdAxfGrMSc/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a openerp-spain-u...@googlegroups.com.

Josean Soroa - LANDOO

unread,
Feb 23, 2017, 4:28:09 AM2/23/17
to Usuarios Odoo / OpenERP en España, bo...@kami.es
Perfecto Borja. Le echaremos un vistazo al cprofile a ver que vemos. De todos modos, veo complicado que nosotros podamos optimizar el código que hace odoo.
En la lista internacional nos han propuesto dejar los procesos lentos en un segundo plano. Es más sencillo de implementar y me fastidia pasar al modo batch, como en los viejos as400, pero me parece una solución bastante eficaz.

Otro problema de los pedidos largos es que el interfaz se va volviendo más y más lento, a partir de unas 60 líneas. Cada línea que borras o modificas hace un "Cargando" muy rápido que recalcula el importe total, pero cada 3 líneas se pone la pantalla gris con el reloj en medio que te para durante algunos segundos. Y todo para recalcular el importe.
Hay alguna forma de desactivar ese recálculo? Creo que si recalcula al grabar el pedido puede ser suficiente.
Puestos a pedir, sería perfecto que el sistema no recalculase en pedidos de más de 50 líneas y si lo hiciera en el resto. Pero con desactivarlo para toda la instancia puede valer.

Gracias a  todos por las aportaciones.

Josean Soroa

Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a openerp-spain-users+unsub...@googlegroups.com.

Juanjo A.

unread,
Jan 16, 2020, 3:54:19 AM1/16/20
to Usuarios Odoo / OpenERP en España
Hola Josean, ¿cómo quedo esto al final?, ¿pudisteis mejorarlo?.

Tengo otro Odoo10 entre manos y nos está ocurriendo igual. He modificado todo el front para facilitar que el agente encuentre y meta en el carrito lo más rápido posible, pero en cuanto aumentan las líneas de pedido, ocurre igual, se vuelve lento.

Aunque he optimizado algunos procesos, como comenta Pedro por ahí, cada línea hace un montón de cosas por detrás. Quizás desactivar el JIT o el tema índices lo mejore.

Estoy liado con una app offline para su conexión a Odoo y me están dando ganas de ponerle un front diferente al B2B para mejorar rapidez, pero es mucho curro.

Ya me cuentas, un saludo.

P.d. si alguien más se anima, que cuente casos de performance, puede ser interesante.

Josean Soroa - LANDOO

unread,
Jan 16, 2020, 8:16:09 AM1/16/20
to Usuarios Odoo / OpenERP en España
Hola Juanjo.
Al final no lo solucionamos porque  el proyecto se canceló por otros motivos.
En cualquier caso, el problema parecía estar en el javascript que intenta actualizar el importe total del pedido en tiempo real, con cada cambio en una línea.
Nuestra idea era desactivar ese recálculo y sólo ejecutarlo al guardar los cambios.
Espero que te sirva de idea.
Otra opción es pasar a v12 o v13, que el javascript ha mejorado bastante. Pero habría que probar el mismo caso, a ver si de verdad está resuelto.

Saludos.

Juanjo A.

unread,
Jan 17, 2020, 4:15:53 AM1/17/20
to Usuarios Odoo / OpenERP en España
Gracias por la info.
Por lo que he ido viendo, algo que influye en mi caso: demasiados writes al tener módulos que heredan módulos, lo que hace que haya problemas de concurrent update en la base de datos, reintentos, y lío al final.
Tenemos bastante custom module.
Miraré lo del javascript, pero eso es trabajo del lado cliente, salvo que haga llamadas al back, por lo que no creo que influya en mi caso.

Un saludo.
Reply all
Reply to author
Forward
0 new messages