J'essaie d'optimiser la requête la plus longue que j'ai jamais écrite en utilisant le MySQL EXPLAIN
mais puisque c'est mon premier je n'arrive pas à comprendre le résultat. Voici la requête et le résultat de l'exécution d'une commande EXPLAIN
:Optimisation d'une requête complexe
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
Les EXPLAIN
résultats dans:
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
Le UNION
au milieu de la requête rejoint ceux qui apparaissent les numéros de qui dans le répertoire avec ceux qui ne pas (ainsi le LEFT JOIN
).
Edit:
Qu'est-ce que cette requête n'est obtenir le plus le dernier message entrant pour chaque numéro et le retourne. Je peux utiliser GROUP BY
car il renvoie le message le plus ancien ... J'ai besoin de la dernière. Ensuite, il la rejoint ces chiffres qui n'existent pas dans le répertoire qui est la raison pour laquelle je vérifie pour WHERE c.number IS NULL.
Quelle version de MySQL? De http://dev.mysql.com/doc/refman/5.7/en/using-explain.html: "Lorsque vous précedez une instruction avec le mot-clé EXPLAIN, MySQL affiche des informations de l'optimiseur sur le plan d'exécution de la requête. , MySQL explique comment il traiterait l'instruction, y compris des informations sur la manière dont les tables sont jointes et dans quel ordre. " – MichaelJCox
Version 5.0.10 Je suppose. Quelle que soit la version livrée avec le dernier XAMPP. – enchance
Basé sur le plan expliquer, je suppose que cette requête est assez rapide. Cela vous donne-t-il des problèmes? Je suppose que je ne suis pas tout à fait sûr de la question. –