sql >> Base de Datos >  >> RDS >> Mysql

Rows_sent:12 Rows_examined:549024 - ¿Cómo optimizar la consulta mySQL?

En primer lugar, hay un problema con su consulta. Usa LEFT JOIN, pero se convierte en un INNER JOIN implícito con su cláusula where:AND (a.list_in='store' OR u.shop_active='1')

¿Por qué esto convierte la UNIÓN IZQUIERDA en un INTERIOR implícito? Debido a que LEFT JOIN producirá valores NULL para u.shop_active cuando no haya un usuario coincidente, pero NULL NUNCA será igual a '1'. Esto convierte la consulta en INNER JOIN porque las filas producidas por OUTER JOIN serán filtradas por la condición WHERE.

Este filtro es también el motivo del problema de rendimiento. Tiene una condición OR entre columnas en dos tablas diferentes. No existe ningún índice que pueda satisfacer tal condición.

Aquí hay otra forma que puede funcionar mejor. Esta versión solo buscará listados donde (a.list_in !='tienda' y u.shop_active ='1') cuando haya menos de 12 listados list_in='tienda'.

Para usar lo siguiente, asegúrese de tener un índice en (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;