2010-09-24 92 views
3

可有一個優化此MySQL查詢優化此MySQL查詢

SELECT submittedform.*, inspectors.first_name, inspectors.last_name 
    FROM (
     SELECT `dinsp`,`departure`,`arrival`,'cabin' as type FROM cabinets 
     UNION 
     SELECT `dinsp`,`departure`,`arrival`,'cockpit' as type FROM cockpits 
     ORDER BY `date_of_inspection` ASC 
     ) AS submittedform 
     INNER JOIN inspectors ON inspectors.id = submittedform.dinsp 

我不想依靠嵌套查詢或者是罰款在這種情況下?也建議我一個cakephp解決方案,但表不能相關。

+0

ORDER BY子句很奇怪 - 而且可能是可移動的。 – 2010-09-24 06:00:46

+0

cakephp不支持UNION,因爲它只是一個mysql的事情iirc。你可以使用dbo來生成查詢,然後在兩者之間添加聯合,如http://tinyurl.com/34olua5 – dogmatic69 2010-09-28 20:40:14

回答

4

你可以試試:

SELECT sf.`dinsp`, sf.`departure`, sf.`arrival`, sf.`type`, i.`first_name`, i.`last_name` 
FROM 
    `inspectors` AS i INNER JOIN (
    SELECT `dinsp`, `departure`, `arrival`, `date_of_inspection`, 'cabin' AS `type` 
    FROM `cabinets` 
    UNION ALL 
    SELECT `dinsp`, `departure`, `arrival`, `date_of_inspection`, 'cockpit' AS `type` 
    FROM `cockpits` 
) AS sf ON sf.`dinsp` = i.`id` 
ORDER BY sf.`date_of_inspection` 

UNION ALL不會重複檢查。始終將ORDER BY子句放在外部查詢中以確保正確排序。

避免使用UNION會更好,因爲它不會允許查詢優化器使用您在dinspdate_of_inspection上可能具有的任何索引。但是這意味着改變模式。

3

到UNION子查詢的另一種是使主查詢分爲兩個部分與聯盟之間:

SELECT c.dinsp, c.departure, d.arrival, 'cabin' AS type, i.first_name, i.last_name 
    FROM cabinets AS c JOIN inspectors AS i ON i.id = c.dinsp 
SELECT c.dinsp, c.departure, d.arrival, 'cockpit' AS type, i.first_name, i.last_name 
    FROM cockpits AS c JOIN inspectors AS i ON i.id = c.dinsp 

目前尚不清楚這會給顯著不同的表現。如果有的話,這會更糟糕,因爲它涉及檢查員表的兩次掃描,但這不可能是非常大的,所以它可能並不重要。您的UNION子查詢減去ORDER BY可能與此相同或略好。在內部查詢中,您的ORDER BY在非選定字段上存在問題;並且需要在我建議的UNION中仔細處理(可能通過選擇額外的列)。

SELECT c.dinsp, c.date_of_inspection, c.departure, d.arrival, 'cabin' AS type, 
     i.first_name, i.last_name 
    FROM cabinets AS c JOIN inspectors AS i ON i.id = c.dinsp 
SELECT c.dinsp, c.date_of_inspection, c.departure, d.arrival, 'cockpit' AS type, 
     i.first_name, i.last_name 
    FROM cockpits AS c JOIN inspectors AS i ON i.id = c.dinsp 
ORDER BY date_of_inspection;