Я пытаюсь оптимизировать самый длинный запрос, который я когда-либо писал, используя MySQL EXPLAIN
, но поскольку это мой первый, я не могу понять результат. Вот запрос и результат от работы в EXPLAIN
команде:Оптимизация сложного запроса
EXPLAIN SELECT pb.name, s1.MessageFrom, s1.MessageText, s1.SendTime, s1.is_unread, s1.Id, s1.autoreply_sent FROM sol_inbound s1
JOIN sol_contactnum c ON s1.MessageFrom = c.number
JOIN sol_phonebk_contactnum USING (contactnum_id)
JOIN sol_phonebk pb USING (phonebk_id)
JOIN sol_message_folder mf ON s1.Id = mf.message_id
WHERE (MessageFrom, SendTime) IN (SELECT MessageFrom, MAX(SendTime) FROM sol_inbound inb
JOIN sol_message_folder mf WHERE inb.Id = mf.message_id
AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
GROUP BY MessageFrom)
AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
UNION
SELECT NULL `name`, s1.MessageFrom, s1.MessageText, s1.SendTime, s1.is_unread, s1.Id, s1.autoreply_sent FROM sol_inbound s1
LEFT JOIN sol_contactnum c ON s1.MessageFrom = c.number
JOIN sol_message_folder mf ON s1.Id = mf.message_id
WHERE c.number IS NULL
AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
AND (MessageFrom, SendTime) IN (SELECT MessageFrom, MAX(SendTime) FROM sol_inbound inb
JOIN sol_message_folder mf WHERE inb.Id = mf.message_id
AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
GROUP BY MessageFrom)
ORDER BY SendTime DESC LIMIT 100
The EXPLAIN
результатов:
id select_type table type possible_keys key key_len ref rows Extra
------ ------------------ ---------------------- ------ ------------------------------------------------------------- ---------------- ------- ---------------------------------------------------- ------ ------------------------
1 PRIMARY pb ALL PRIMARY (NULL) (NULL) (NULL) 303
1 PRIMARY sol_phonebk_contactnum ref PRIMARY,phonebk_id1_idx,contactnum_id1_idx,phonebk_contactnum PRIMARY 4 googlep1_solane.pb.phonebk_id 1 Using index
1 PRIMARY c eq_ref PRIMARY,number_idx PRIMARY 4 googlep1_solane.sol_phonebk_contactnum.contactnum_id 1
1 PRIMARY s1 ref PRIMARY,message_from_idx message_from_idx 243 googlep1_solane.c.number 1 Using where
1 PRIMARY mf eq_ref PRIMARY PRIMARY 22 const,googlep1_solane.s1.Id,const,const 1 Using where; Using index
2 DEPENDENT SUBQUERY inb index PRIMARY message_from_idx 243 (NULL) 1
2 DEPENDENT SUBQUERY mf eq_ref PRIMARY PRIMARY 22 const,googlep1_solane.inb.Id,const,const 1 Using where; Using index
3 UNION s1 ALL PRIMARY (NULL) (NULL) (NULL) 877 Using where
3 UNION c ref number_idx number_idx 243 googlep1_solane.s1.MessageFrom 1 Using where; Using index
3 UNION mf eq_ref PRIMARY PRIMARY 22 const,googlep1_solane.s1.Id,const,const 1 Using where; Using index
4 DEPENDENT SUBQUERY inb index PRIMARY message_from_idx 243 (NULL) 1
4 DEPENDENT SUBQUERY mf eq_ref PRIMARY PRIMARY 22 const,googlep1_solane.inb.Id,const,const 1 Using where; Using index
(NULL) UNION RESULT <union1,3> ALL (NULL) (NULL) (NULL) (NULL) (NULL) Using filesort
UNION
в середине запроса присоединяется к тем, кто есть номера появляются в телефонной книге, с теми, кто нет (таким образом, LEFT JOIN
).
Edit:
Что этот запрос делает это получить самую последнюю Inbound сообщение для каждого номера и возвращает его. Я могу использовать GROUP BY
, так как он возвращает самое старое сообщение ... Мне нужно последнее. Затем он присоединяется к ней те номера, которые не существуют в телефонной книге, поэтому я проверить WHERE c.number IS NULL.
Какая версия MySQL? Из http://dev.mysql.com/doc/refman/5.7/en/using-explain.html: «Когда вы предшествуете инструкции с ключевым словом EXPLAIN, MySQL отображает информацию от оптимизатора о плане выполнения запроса. , MySQL объясняет, как он обрабатывает этот оператор, включая информацию о том, как соединяются таблицы и в каком порядке ». – MichaelJCox
Версия 5.0.10 Предполагаю. Какая версия поставляется с последним XAMPP. – enchance
Основываясь на плане объяснений, я бы предположил, что этот запрос довольно быстрый. Это дает вам проблемы? Наверное, я не совсем уверен, в чем вопрос. –