Monday, March 25, 2024
4 changes · 17.0
Enhancements to existing features
Users can now retry sending failed Mexican invoices (CFDI) directly using a retry button, instead of having to navigate back to the send & print option. The system automatically handles PDF generation when retrying, making the process more efficient and user-friendly.
Original PR description
Before: when a CFDI wasn't created successfully, the retry button wasn't shown to force the user to go back to the send & print button to generate the invoice PDF. Now: the retry button is shown and the generation of the PDF is done by manually triggering the send and print process. task-3687266
The Data Cleaning App has been significantly optimized to run much faster. The update removes inefficient database queries that were slowing down the application, resulting in dramatic speed improvements—from several minutes down to seconds for large datasets. This fix also prevents the app from crashing when processing very large amounts of data.
Original PR description
# Issue: Data Cleaning App is slow. # Analyze: - There is no check on model duplication to generate subqueries. - For each domain search, the queries have subqueries joined with "UNION" which are…
# Issue: Data Cleaning App is slow. # Analyze: - There is no check on model duplication to generate subqueries. - For each domain search, the queries have subqueries joined with "UNION" which are slow and can't be optimized by the Planner. # Fix: - Remove duplicated models which generate the same condition. - Avoid subqueries and make one big query with each one of the subqueries. # Benchmark: | # Input data | Before PR | After PR | |:-------------:|:----------:|:---------:| | 5144 dmr (3 models) | 1,91 s | 0,31 s | | 974 931 dmr (3 models) | 7:09 min | 33,86 s ( Hot cache : 5,62s) | | 8 804 632 dmr (6 models) | Crash after 5:30 min | 1:19 min | # Note: - I tried it with the biggest database I could access, I didn't crash but on big databases with a lot of related model, there would be a bunch of LEFT JOIN and that could have a Memory Limit. (In any case it wouldn't work with current implementation) - The index could help on the planner, but it is not required (while it can't hurt to have an index on a Many2One). # Related task: opw-3696044 Speedscope in attachment in the task Forward-Port-Of: odoo/enterprise#56536
This update improves how Odoo checks which companies a user can access by simplifying the database queries. Previously, the system was creating inefficient queries that could take hours to complete in large databases. The change restructures these rules to generate simpler, faster queries that the database can process more efficiently, resulting in significantly better performance across the system.
This update improves how the system checks company access permissions in the database, making queries run significantly faster. Previously, the system was creating duplicate database queries that caused PostgreSQL to take hours to complete in some cases. The fix simplifies the query logic so the database can process requests more efficiently, resulting in better performance across multiple modules that use company-based access controls.
Original PR description
When we use the `|` (or) version of this rule the ORM generates two sub-queries when checking the company. This causes sub-optimal and in some cases really bad planning for the queries and thus PG…
When we use the `|` (or) version of this rule the ORM generates two sub-queries when checking the company. This causes sub-optimal and in some cases really bad planning for the queries and thus PG takes hours to complete them.
Example (formatted):
```sql
SELECT "mrp_routing_workcenter".id
FROM "mrp_routing_workcenter"
LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
AND ( ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE ("mrp_bom"."company_id" in (1))
)
)
OR ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE "mrp_bom"."company_id" IS NULL
)
)
)
ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
"mrp_routing_workcenter__bom_id"."id",
"mrp_routing_workcenter"."sequence",
"mrp_routing_workcenter"."id"
```
If we use the single term version the generated query has only one sub-query:
```sql
SELECT "mrp_routing_workcenter".id
FROM "mrp_routing_workcenter"
LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
AND ( ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE (("mrp_bom"."company_id" in (1))
OR ("mrp_bom"."company_id" IS NULL))
)
)
)
ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
"mrp_routing_workcenter__bom_id"."id",
"mrp_routing_workcenter"."sequence",
"mrp_routing_workcenter"."id"
```
In this version PG is able to produce a better query plan resulting in better execution times.
Also, the `company_id` field is required on some models, so the "= False" comparison is useless.
Forward-Port-Of: odoo/enterprise#59288
Forward-Port-Of: odoo/enterprise#58756Original PR description
When we use the `|` (or) version of this rule the ORM generates two sub-queries when checking the company. This causes sub-optimal and in some cases really bad planning for the queries and thus PG…
When we use the `|` (or) version of this rule the ORM generates two sub-queries when checking the company. This causes sub-optimal and in some cases really bad planning for the queries and thus PG takes hours to complete them.
Example (formatted):
```sql
SELECT "mrp_routing_workcenter".id
FROM "mrp_routing_workcenter"
LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
AND ( ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE ("mrp_bom"."company_id" in (1))
)
)
OR ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE "mrp_bom"."company_id" IS NULL
)
)
)
ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
"mrp_routing_workcenter__bom_id"."id",
"mrp_routing_workcenter"."sequence",
"mrp_routing_workcenter"."id"
```
If we use the single term version the generated query has only one sub-query:
```sql
SELECT "mrp_routing_workcenter".id
FROM "mrp_routing_workcenter"
LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
AND ( ("mrp_routing_workcenter"."bom_id" in (
SELECT "mrp_bom".id
FROM "mrp_bom"
WHERE (("mrp_bom"."company_id" in (1))
OR ("mrp_bom"."company_id" IS NULL))
)
)
)
ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
"mrp_routing_workcenter__bom_id"."id",
"mrp_routing_workcenter"."sequence",
"mrp_routing_workcenter"."id"
```
In this version PG is able to produce a better query plan resulting in better execution times.
Also, the `company_id` field is required on some models, so the "= False" comparison is useless.
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#158913
Forward-Port-Of: odoo/odoo#157861