Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Rows_sent:12 Rows_examined:549024 - Wie kann man die MySQL-Abfrage optimieren?

Zunächst einmal gibt es ein Problem mit Ihrer Abfrage. Sie verwenden LEFT JOIN, aber Sie verwandeln sich in einen impliziten INNER JOIN mit Ihrer where-Klausel:AND (a.list_in='store' OR u.shop_active='1')

Warum wird aus dem LEFT JOIN ein implizites INNER? Weil der LEFT JOIN NULL-Werte für u.shop_active erzeugt, wenn es keinen passenden Benutzer gibt, aber NULL wird NIE gleich '1' sein. Dadurch wird die Abfrage zu einem INNER JOIN, da alle vom OUTER JOIN erzeugten Zeilen durch die WHERE-Bedingung gefiltert werden.

Dieser Filter ist auch der Grund für das Performance-Problem. Sie haben eine ODER-Bedingung zwischen Spalten in zwei verschiedenen Tabellen. Es gibt keinen Index, der eine solche Bedingung erfüllen kann.

Hier ist ein anderer Weg, der möglicherweise besser funktioniert. Diese Version sucht nur nach Einträgen mit (a.list_in !='store' und u.shop_active ='1'), wenn es weniger als 12 list_in='store'-Einträge gibt.

Um Folgendes zu verwenden, stellen Sie sicher, dass Sie einen Index für (list_in, end_time) haben

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;