2014-07-01 2 views
0

J'ai une requête MySql SELECT qui utilise environ 6 tables, entre les 2 tables ont plus de 4000 dossiers, la requête que je utilise est:Comment améliorer la requête SELECT multi-tables?

SELECT DISTINCT r.*, 
       p.name AS product, 
       p.price, 
       p.tax, 
       l.name AS license_status, 
       CONCAT(c.firstname, ' ', c.lastname) AS customer, 
       CONCAT(cc.firstname, ' ', cc.lastname) AS license_customer, 
       cc.telephone AS license_customer_mobile 
FROM order_license r 
LEFT JOIN customer c ON (c.customer_id = r.customer_id) 
LEFT JOIN order_product p ON (p.order_id = r.order_id 
           AND r.product_id = p.product_id) 
LEFT JOIN license_status l ON (l.license_status_id = r.license_status_id) 
LEFT JOIN customer cc ON (cc.customer_id = r.license_customer_id) 
WHERE r.license_status_id = '7' 
    AND r.validity > 0 
ORDER BY r.end_date ASC LIMIT 0,10 

Le problème est son prend environ 1 min pour afficher les enregistrements, ce qui est très élevé pour un si petit nombre d'enregistrements. Le serveur MySql est un VPS Linode qui est assez rapide aussi. Maintenant, je n'ai aucune idée de ce qui ne va pas.

J'ai essayé d'ajouter des index et supprimé LEFT JOINS (comme indiqué dans la requête ci-dessous), mais les résultats sont presque les mêmes.

SELECT r.*, 
     p.name AS product, 
     p.price, 
     p.tax, 
     l.name AS license_status, 
     CONCAT(c.firstname, ' ', c.lastname) AS customer, 
     CONCAT(cc.firstname, ' ', cc.lastname) AS license_customer, 
     cc.telephone AS license_customer_mobile 
FROM order_license r, 
    order_product p, 
    license_status l, 
    customer c, 
    customer cc 
WHERE (p.order_id = r.order_id 
     AND r.product_id = p.product_id) 
    AND (l.license_status_id = r.license_status_id) 
    AND (c.customer_id = r.customer_id) 
    AND (cc.customer_id = r.license_customer_id) 
    AND r.license_status_id = '7' 
    AND r.validity > 0 
ORDER BY r.end_date ASC LIMIT 0,10 

Aidez-nous s'il vous plaît. Vous remplacez les conditions ON dans votre clause WHERE.

+0

Vous connaissez le power_ _Magic de (http://dev.mysql.com/doc/refman/5.0/en/explain-output.html) [SELECT EXPLIQUER]? – s1lv3r

+0

La première requête utilise des jointures à gauche inutiles et répète chaque condition de jointure dans 'WHERE'. La seconde est encore pire. Sans condition de jointure, vous obtenez un produit cartésien de chaque ligne de toutes ces tables, qui n'est filtré que dans le 'WHERE'. – shmosel

+0

Pouvez-vous me donner l'info de votre commande_license? Quelle est la clé primaire de cette table? – wrecklez

Répondre

0

changement:

WHERE (p.order_id = r.order_id 
    AND r.product_id = p.product_id) 
AND (l.license_status_id = r.license_status_id) 
AND (cc.customer_id = r.license_customer_id) 
AND r.license_status_id = '7' 
AND r.validity > 0 
ORDER BY r.end_date ASC LIMIT 0,10 

à

WHERE r.license_status_id = '7' 
AND r.validity > 0 
ORDER BY r.end_date ASC LIMIT 0,10 
0

pouvez-vous essayer ce code? répondrons dès que possible, sinon aider

SELECT 
    R.*, 
    P.name AS product, 
    P.price, 
    P.tax, 
    L.name AS license_status, 
    CONCAT(C.firstname, ' ', C.lastname) AS customer 
    CONCAT(CC.firstname, ' ', CC.lastname) AS license_customer 
    CC.telephone AS license_customer_mobile 
FROM order_license R 
    LEFT JOIN customer C 
    ON C.customer_id = R.customer_id 
    LEFT JOIN order_product P 
    ON P.order_id = R.order_id 
     AND P.product_id = R.product_id 
    LEFT JOIN license_status L 
    ON L.license_status_id = R.license_status_id 
    LEFT JOIN customer CC 
    ON CC.customer_id = R.customer_id 
WHERE R.validity > 0 
    AND R.license_status_id = 7 
GROUP BY R.order_license_id 
ORDER BY R.end_date LIMIT 10 
+0

Merci pour votre aide mais le temps pris est presque le même que le mien. – seopower

Questions connexes