Content
View differences
Updated by Bruno Pagno over 1 year ago
During the development of the [equals\_with\_descendants.rb](https://github.com/opf/openproject/blob/dev/app/models/queries/operators/custom_fields/hierarchies/equals_with_descendants.rb) operator for filtering work packages a possible optimization was identified.
We seem to be duplicating a lot of joins around custom fields.
We should:
* Investigate how much of this is expected behaviour
* Investigate if there is an alternate solution
* Implement and fix this behaviour
This was identified during [a code review](https://github.com/opf/openproject/pull/17247#pullrequestreview-2462029224)
Example query
```sql
SELECT
"work_packages"."id"
"work_packages"."id"
FROM
"work_packages"
LEFT
"work_packages"
LEFT OUTER JOIN "projects" ON "projects"."id" = "work_packages"."project_id"
WHERE
(
(
WORK_PACKAGES.ID
(
(
WORK_PACKAGES.ID IN (
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT OUTER JOIN CUSTOM_VALUES ON CUSTOM_VALUES.CUSTOMIZED_TYPE = 'WorkPackage'
AND
AND CUSTOM_VALUES.CUSTOMIZED_ID = WORK_PACKAGES.ID
AND
AND CUSTOM_VALUES.CUSTOM_FIELD_ID = 541
JOIN
JOIN CUSTOM_FIELDS_TYPES ON CUSTOM_FIELDS_TYPES.TYPE_ID = WORK_PACKAGES.TYPE_ID
AND
AND CUSTOM_FIELDS_TYPES.CUSTOM_FIELD_ID = 541
JOIN
JOIN CUSTOM_FIELDS_PROJECTS ON CUSTOM_FIELDS_PROJECTS.PROJECT_ID = WORK_PACKAGES.PROJECT_ID
AND
AND CUSTOM_FIELDS_PROJECTS.CUSTOM_FIELD_ID = 541
WHERE
(
CUSTOM_VALUES.VALUE
WHERE
(
CUSTOM_VALUES.VALUE IS NULL
OR
OR CUSTOM_VALUES.VALUE NOT IN ('14')
)
)
)
AND
)
)
)
AND (PROJECTS.ID IN (6))
)
AND
)
AND (
WORK_PACKAGES.ID
WORK_PACKAGES.ID IN (
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT OUTER JOIN CUSTOM_VALUES ON CUSTOM_VALUES.CUSTOMIZED_TYPE = 'WorkPackage'
AND
AND CUSTOM_VALUES.CUSTOMIZED_ID = WORK_PACKAGES.ID
AND
AND CUSTOM_VALUES.CUSTOM_FIELD_ID = 541
JOIN
JOIN CUSTOM_FIELDS_TYPES ON CUSTOM_FIELDS_TYPES.TYPE_ID = WORK_PACKAGES.TYPE_ID
AND
AND CUSTOM_FIELDS_TYPES.CUSTOM_FIELD_ID = 541
JOIN
JOIN CUSTOM_FIELDS_PROJECTS ON CUSTOM_FIELDS_PROJECTS.PROJECT_ID = WORK_PACKAGES.PROJECT_ID
AND
AND CUSTOM_FIELDS_PROJECTS.CUSTOM_FIELD_ID = 541
WHERE
(
CUSTOM_VALUES.VALUE
WHERE
(
CUSTOM_VALUES.VALUE IS NULL
OR
OR CUSTOM_VALUES.VALUE NOT IN ('14')
)
)
)
AND
)
)
)
AND "work_packages"."id" IN (
SELECT
"work_packages"."id"
FROM
"work_packages"
INNER
SELECT
"work_packages"."id"
FROM
"work_packages"
INNER JOIN "projects" ON "projects"."id" = "work_packages"."project_id"
INNER
INNER JOIN "enabled_modules" ON "projects"."id" = "enabled_modules"."project_id"
AND
AND "enabled_modules"."name" IN ('work_package_tracking')
AND
AND "projects"."active" = TRUE
WHERE
"projects"."active"
WHERE
"projects"."active" = TRUE
)
)
ORDER BY
WORK_PACKAGES.ID
WORK_PACKAGES.ID
```
We seem to be duplicating a lot of joins around custom fields.
We should:
* Investigate how much of this is expected behaviour
* Investigate if there is an alternate solution
* Implement and fix this behaviour
This was identified during [a code review](https://github.com/opf/openproject/pull/17247#pullrequestreview-2462029224)
Example query
```sql
SELECT
"work_packages"."id"
"work_packages"."id"
FROM
"work_packages"
LEFT
"work_packages"
LEFT
WHERE
(
(
WORK_PACKAGES.ID
(
(
WORK_PACKAGES.ID
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
AND
AND
AND
AND
JOIN
JOIN
AND
AND
JOIN
JOIN
AND
AND
WHERE
(
CUSTOM_VALUES.VALUE
WHERE
(
CUSTOM_VALUES.VALUE
OR
OR
)
)
)
AND
)
)
)
AND
)
AND
)
AND
WORK_PACKAGES.ID
WORK_PACKAGES.ID
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
SELECT
WORK_PACKAGES.ID
FROM
WORK_PACKAGES
LEFT
AND
AND
AND
AND
JOIN
JOIN
AND
AND
JOIN
JOIN
AND
AND
WHERE
(
CUSTOM_VALUES.VALUE
WHERE
(
CUSTOM_VALUES.VALUE
OR
OR
)
)
)
AND
)
)
)
AND
SELECT
"work_packages"."id"
FROM
"work_packages"
INNER
SELECT
"work_packages"."id"
FROM
"work_packages"
INNER
INNER
INNER
AND
AND
AND
AND
WHERE
"projects"."active"
WHERE
"projects"."active"
)
)
ORDER BY
WORK_PACKAGES.ID
WORK_PACKAGES.ID
```