Create payment line combo box for entry line is very slow

Bug #1195204 reported by Colin Newell
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Odoo Addons (MOVED TO GITHUB)
Triaged
Low
OpenERP's Framework R&D

Bug Description

If you go to Payment Orders, Create Payment, then go to Create Payment Line and activate the combo box to select a payment on the entry line entry a very innefficient query is executed. On a live system we are using this takes 2-3 minutes to run. This is 2-3 minutes to select every single entry to pay which is debilitating.

The query being emitted that is so painful is this,

  SELECT id
  FROM account_move_line l
  WHERE account_id IN (
      select id
      FROM account_account
      WHERE type='payable' AND active
    )
    AND reconcile_id IS null
    AND credit > 0
    AND (
      SELECT
        CASE
          WHEN l.amount_currency < 0
          THEN - l.amount_currency
          ELSE l.credit
          END - coalesce(sum(pl.amount_currency), 0)
      FROM payment_line pl
        INNER JOIN payment_order po ON (pl.order_id = po.id)
      WHERE move_line_id = l.id
        AND po.state != 'cancel'
    ) > 0
    AND l.state <> 'draft'
    AND l.period_id IN (
      SELECT id
      FROM account_period
      WHERE fiscalyear_id IN (2)
    )

The code that is generating this comes from two places,

addons/account_payment/account_move_line.py in the method _to_pay_search
addons/account/account_move_line.py in the method _query_get

By altering the query to pull the account_period query out I was able to make the query run an order of magnitude faster. With Postgres this was possible,

with periods as (
    SELECT id
    FROM account_period
    WHERE fiscalyear_id IN (2)
)

  SELECT id
  FROM account_move_line l
  WHERE
    l.state <> 'draft'
    AND reconcile_id IS null
    AND credit > 0
  AND account_id IN (
      select id
      FROM account_account
      WHERE type='payable' AND active
    )
    AND (
      SELECT
        CASE
          WHEN l.amount_currency < 0
          THEN - l.amount_currency
          ELSE l.credit
          END - coalesce(sum(pl.amount_currency), 0)
      FROM payment_line pl
        INNER JOIN payment_order po ON (pl.order_id = po.id)
      WHERE move_line_id = l.id
        AND po.state != 'cancel'
    ) > 0
    AND l.period_id IN (select id from periods)

To prove this had a practical positive effect I came up with a really dodgy hack for OpenERP that optimised the query in that situation. Assuming you have a reasonable size dataset this should prove that a performance optimisation is worth performing. I'm not suggesting that you should use this patch however as it's obviously very brittle and generally not a good idea.

Revision history for this message
Colin Newell (colin-newell) wrote :
Revision history for this message
Twinkle Christian(OpenERP) (tch-openerp) wrote :

Hello Colin,

Are you still facing this issue ? Please provide your notification for this .

Thanks

Changed in openobject-addons:
status: New → Incomplete
Revision history for this message
Colin Newell (colin-newell) wrote :

Yes.

Revision history for this message
Colin Newell (colin-newell) wrote :

I notice that you have marked this as incomplete - "Cannot be verified, the reporter needs to give more info."

What information do you need?

Changed in openobject-addons:
status: Incomplete → Triaged
assignee: nobody → OpenERP's Framework R&D (openerp-dev-framework)
importance: Undecided → Low
Revision history for this message
Olivier Dony (Odoo) (odo-openerp) wrote :

Hi Colin,

I have reproduced this behavior on the customer's database and will be investigating it soon. You don't need to provide any additional info at this point.

Thanks,

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.