Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql Query Optimization with many left joins

I have a Doctrine query that is taking seconds to run. I'd like to make sure that it's going as fast as I can make it. The query is the following (coming from Doctrine):

SELECT DISTINCT task.id AS id0,
                task.rate AS rate1,
                task.revised_rate AS revised_rate2,
                task.title AS title3,
                task.points AS points4,
                task.due AS due5,
                task.created AS created6,
                invoice.id AS id7,
                invoice.title AS title8,
                company.id AS id9,
                company.customer_code AS customer_code10,
                taskStatus.id AS id11,
                taskStatus.title AS title12,
                priority.id AS id13,
                taskUser.id AS id14,
                taskUser.firstname AS firstname15,
                taskUser.lastname AS lastname16,
                invoiceUser.id AS id17,
                invoiceUser.firstname AS firstname18,
                invoiceUser.lastname AS lastname19,
                invoiceStatus.id AS id20,
                invoiceStatus.title AS title21,
                opportunity.id AS id22,
                opportunity.name AS name23,
                SUM(slip.stop - slip.start) AS sclr24,
                task.projected_minutes AS projected_minutes25
FROM task task
INNER JOIN invoice invoice ON task.invoice_id = invoice.id
AND (invoice.deleted IS NULL)
INNER JOIN company company ON invoice.company_id = company.id
LEFT JOIN task_status taskStatus ON task.status_id = taskStatus.id
AND (taskStatus.deleted IS NULL)
LEFT JOIN slip slip ON task.id = slip.task_id
AND (slip.deleted IS NULL)
LEFT JOIN fos_user taskUser ON task.user_id = taskUser.id
AND (taskUser.deleted IS NULL)
LEFT JOIN priority priority ON task.priority_id = priority.id
AND (priority.deleted IS NULL)
LEFT JOIN task_comment taskComment ON task.id = taskComment.task_id
AND (taskComment.deleted IS NULL)
LEFT JOIN task_file taskFile ON task.id = taskFile.task_id
AND (taskFile.deleted IS NULL)
LEFT JOIN task_step taskStep ON task.id = taskStep.task_id
AND (taskStep.deleted IS NULL)
LEFT JOIN fos_user invoiceUser ON invoice.user_id = invoiceUser.id
AND (invoiceUser.deleted IS NULL)
LEFT JOIN invoice_status invoiceStatus ON invoice.status_id = invoiceStatus.id
AND (invoiceStatus.deleted IS NULL)
LEFT JOIN opportunity opportunity ON invoice.opportunity_id = opportunity.id
LEFT JOIN fos_user slipUser ON slip.user_id = slipUser.id
AND (slipUser.deleted IS NULL)
WHERE (taskStatus.id IN (3)
       AND slipUser.id IN (605))
  AND (task.deleted IS NULL)
GROUP BY task.id,
         company.id,
         taskUser.id,
         taskStatus.id,
         invoice.id,
         invoiceUser.id,
         invoiceStatus.id,
         opportunity.id,
         priority.id
ORDER BY priority.id ASC, task.due ASC, company.customer_code ASC, taskUser.firstname ASC, taskUser.lastname ASC, task.points ASC, task.title ASC, taskStatus.title ASC, task.created ASC, invoice.title ASC, invoiceUser.firstname ASC, invoiceUser.lastname ASC, invoiceStatus.title ASC, opportunity.name ASC LIMIT 50
OFFSET 0

And here is a link to the explain.

Task table and indexes

Invoice table and indexes

Company table and indexes

Task status table and indexes

Slip table and indexes

fos_user table and indexes

Priority table and indexes

Task comment table and indexes

Task file table and indexes

Task step table and indexes

Invoice status table

Opportunity table

Is there something I can be doing better with the joins? Make them subselects?

Any comments are appreciated!

like image 872
nwalke Avatar asked Jan 31 '26 22:01

nwalke


1 Answers

You can try a partial index.

CREATE INDEX idx_deleted_rows (some_id) ON some_table WHERE (deleted IS NULL);
like image 121
edze Avatar answered Feb 03 '26 19:02

edze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!