In case you have your own slow SQL query, you can optimize it automatically here.
For the query above, the following recommendations will be helpful as part of the SQL tuning process.
You'll find 3 sections below:
CREATE INDEX tassignments_idx_licence_id ON "test"."tAssignments" ("licence_id");
CREATE INDEX tlicences_idx_id ON "tLicences" ("id");
CREATE INDEX tpurchases_idx_id ON "tPurchases" ("id");
SELECT
*
FROM
test.tPurchases AS tPurchases
INNER JOIN
test.tLicences
ON tLicences.purchase_id = tPurchases.id
LEFT JOIN
(
SELECT
purchase_id,
SUM(CASE assignment_newer_id IS NOT NULL
WHEN true THEN 1
WHEN false THEN 0 END) AS prchs_quantity_assigned,
SUM(CASE assignment_newer_id IS NULL
AND current_timestamp BETWEEN licence_availability_start AND licence_availability_end
WHEN true THEN 1
WHEN false THEN 0 END) AS prchs_quantity_notAssignedAndCanBeAssigned,
SUM(CASE assignment_newer_id IS NULL
AND current_timestamp < licence_availability_start
WHEN true THEN 1
WHEN false THEN 0 END) AS prchs_quantity_notAssignedAndCannotBeAssigned
FROM
(SELECT
tPurchases.id AS purchase_id,
tPurchases.date_ AS purchase_date,
tLicences.id AS licence_id,
GREATEST(tPurchases.date_,
older.end_,
older.start + '1 day'::interval) AS licence_availability_start,
CASE
WHEN newer.id IS NULL THEN 'infinity'
ELSE newer.start - '1 day'::interval END AS licence_availability_end,
COALESCE(newer.start,
'infinity') AS licence_availability_uninstallBy,
older.id AS assignment_older_id,
older.start AS assignment_older_start,
older.end_ AS assignment_older_end,
newer.id AS assignment_newer_id,
newer.start AS assignment_newer_start,
newer.end_ AS assignment_newer_end
FROM
test.tLicences
INNER JOIN
test.tPurchases
ON tPurchases.id = tLicences.purchase_id
LEFT JOIN
test.tAssignments AS older
ON (
NOT older.deleted
AND older.licence_id = tLicences.id
)
LEFT JOIN
test.tAssignments AS newer
ON (
NOT newer.deleted
AND newer.id <> older.id
AND newer.licence_id = older.licence_id
)
WHERE
NOT tLicences.deleted
UNION
SELECT
tPurchases.id AS purchase_id,
tPurchases.date_ AS purchase_date,
tLicences.id AS licence_id,
tPurchases.date_ AS licence_availability_start,
oldest.start - '1 day'::interval AS licence_availability_end,
oldest.start AS licence_availability_uninstallBy,
NULL AS assignment_older_id,
NULL AS assignment_older_start,
NULL AS assignment_older_end,
oldest.id AS assignment_newer_id,
oldest.start AS assignment_newer_start,
oldest.end_ AS assignment_newer_end
FROM
test.tLicences
INNER JOIN
test.tPurchases
ON tPurchases.id = tLicences.purchase_id
INNER JOIN
test.tAssignments AS oldest
ON oldest.licence_id = tLicences.id
WHERE
NOT tLicences.deleted
AND NOT oldest.deleted
) AS periodsOfAvailability_start
WHERE
(
assignment_newer_id IS NULL
OR assignment_newer_end IS NULL
)
GROUP BY
purchase_id) AS purchase_quantities_assignnments
ON purchase_quantities_assignnments.purchase_id = tPurchases.id
WHERE
tLicences.id = 19