Skip to content
Snippets Groups Projects
Commit 088b9c23 authored by Moises Lopez's avatar Moises Lopez
Browse files

[REF] account_check_printing: Speed-up payment creation


The method constraint to validate the Check Number is slow

1. Analyzing the following query:

```sql
SELECT
    payment.check_number,
    move.journal_id
FROM
    account_payment payment
    JOIN account_move move ON move.id = payment.move_id
    JOIN account_journal journal ON journal.id = move.journal_id,
    account_payment other_payment
    JOIN account_move other_move ON other_move.id = other_payment.move_id
WHERE
    payment.check_number::integer = other_payment.check_number::integer
    AND move.journal_id = other_move.journal_id
    AND payment.id != other_payment.id
    AND payment.id IN (1085159)
    AND move.state = 'posted'
    AND other_move.state = 'posted';
```

The output is:

    Planning Time: 3.354 ms
    Execution Time: 2514.660 ms

Discarding null values

```diff
    AND other_move.state = 'posted';
+    AND payment.check_number IS NOT NULL
+    AND other_payment.check_number IS NOT NULL
```

The output is

    Planning Time: 3.216 ms
    Execution Time: 0.140 ms

2. The constraint is computed even if the payment is not a check (check_number is empty)

Returning early save useless extra computating
It is not needed to compare falsy values for duplicated for whole table

3. The validation to check is it not a number is not optimal

It is transforming the string -> integer -> string to check if the string is not a number
but it is enough using only string -> integer not needed to transform to string again

    python3 -m timeit -u msec -s "check_numbers = [str(i) for i in range(1000000)]" "[str(int(i)) for i in check_numbers]"
        > 1 loop, best of 5: 323 msec per loop

    python3 -m timeit -u msec -s "check_numbers = [str(i) for i in range(1000000)]" "[int(i) for i in check_numbers]"
        > 2 loops, best of 5: 135 msec per loop

It is better but not enough, using `str.isdigit` method is 5x faster than original approach

    python3 -m timeit -u msec -s "check_numbers = [str(i) for i in range(1000000)]" "[i.isdecimal() for i in check_numbers]"
        > 5 loops, best of 5: 64 msec per loop

closes odoo/odoo#83851

X-original-commit: 31e0ed8c
Signed-off-by: default avatarOlivier Colson <oco@odoo.com>
parent e8309535
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment