优化这个mysql查询

时间:2010-09-24 05:42:04

标签: php mysql cakephp

有人可以优化这个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解决方案,但表格无关。

2 个答案:

答案 0 :(得分: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上可能拥有的任何索引。但这意味着要改变架构。

答案 1 :(得分:3)

UNION子查询的替代方法是将主查询分为两部分,其中包含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

目前尚不清楚这会产生明显不同的表现。如果有的话,它会更糟,因为它涉及Inspectors表的两次扫描,但这可能不是很大,所以它可能并不重要。您的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;