Mysql
 sql >> Base de données >  >> RDS >> Mysql

Rows_sent :12 Rows_examined :549024 - comment optimiser la requête mySQL ?

Tout d'abord, il y a un problème avec votre requête. Vous utilisez LEFT JOIN, mais vous vous transformez en INNER JOIN implicite avec votre clause where :AND (a.list_in='store' OR u.shop_active='1')

Pourquoi cela transforme-t-il le LEFT JOIN en un INNER implicite ? Parce que LEFT JOIN produira des valeurs NULL pour u.shop_active lorsqu'il n'y a pas d'utilisateur correspondant, mais NULL ne sera JAMAIS égal à '1'. Cela transforme la requête en INNER JOIN car toutes les lignes produites par OUTER JOIN seront filtrées par la condition WHERE.

Ce filtre est également la cause du problème de performances. Vous avez une condition OR entre les colonnes de deux tables différentes. Aucun index ne peut satisfaire une telle condition.

Voici une autre méthode qui peut être plus performante. Cette version ne recherchera les annonces où (a.list_in !='store' et u.shop_active ='1') que lorsqu'il y a moins de 12 listes list_in='store'.

Pour utiliser ce qui suit, assurez-vous d'avoir un index sur (list_in, end_time)

SELECT * FROM
(
    SELECT a.listing_id, a.name, a.item_price, a.max, a.nb, a.currency,
           a.end_time, a.closed, a.bold, a.hl, a.buy_price, a.is_offer, a.reserve,
           a.owner_id, a.postage_amount, a.fb_current_bid, a.type, a.start_time,
           a.is_relisted_item, a.enable
     FROM db_listings a
    WHERE list_in = 'store'
     a.active=1 AND
     a.approved=1 AND 
     a.deleted=0 AND 
     a.creation_in_progress=0 AND
     a.closed=0
    ORDER BY end_time 
    LIMIT 12 
    )
    UNION ALL
    (
        SELECT a.listing_id, a.name, a.item_price, a.max, a.nb, a.currency,
           a.end_time, a.closed, a.bold, a.hl, a.buy_price, a.is_offer, a.reserve,
           a.owner_id, a.postage_amount, a.fb_current_bid, a.type, a.start_time,
           a.is_relisted_item, a.enable
        FROM db_listings a
        JOIN users u 
          ON a.owner_id = u.user_id
         AND u.shop_active = '1'
       WHERE list_in != 'store' AND
       a.active=1 AND
       a.approved=1 AND 
       a.deleted=0 AND 
       a.creation_in_progress=0 AND
       a.closed=0
       ORDER BY end_time 
       LIMIT 12 
    )
) sq
ORDER BY list_in, end_time
LIMIT 12;