2013-04-02 97 views
3

我有一個需要幾秒鐘才能運行的Doctrine查詢。我想確保它能夠儘快完成。查詢是(從教義來)如下:許多左連接的PostgreSQL查詢優化

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 

這裏是一個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

有什麼我可以做與加入更好?讓他們子選?

任何意見都表示讚賞!

+2

**您需要向我們展示表和索引定義。**診斷慢查詢需要全表和索引定義,而不僅僅是描述或釋義。也許你的表格定義不好。也許索引沒有正確創建。也許你沒有一個你認爲你做過的那個專欄的索引。沒有看到表和索引定義,我們不能說。 –

+0

這就是我所害怕的。讓我把它們放在那裏。 – tubaguy50035

+0

表格之間的關係是什麼? – didierc

回答

1

你可以試試partial index

CREATE INDEX idx_deleted_rows (some_id) ON some_table WHERE (deleted IS NULL); 
+0

你會對此建議哪些行? – tubaguy50035

+0

如果解釋看起來像這樣:使用some_table上的idx_abc進行索引掃描,後跟「Filter:(some_table.deleted IS NULL)」。在本例中,除了idx_abc之外,還可以添加部分索引。 – edze