Оптимизировать этот запрос MySQL - PullRequest
3 голосов
/ 24 сентября 2010

Может ли кто-нибудь оптимизировать этот запрос 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 ]

4 голосов
/ 24 сентября 2010

Вы можете попробовать:

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, поскольку это не позволит оптимизатору запросов использовать любой индекс, который у вас может быть dinsp и date_of_inspection.Но это будет означать изменение схемы.

3 голосов
/ 24 сентября 2010

Альтернативой подзапросу 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

Не ясно, что это даст значительно отличную производительность. Во всяком случае, это было бы хуже, так как это включает в себя два сканирования таблицы инспекторов, но это вряд ли будет очень большим, так что это может не иметь большого значения. Ваш подзапрос 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...