För det första är det ett problem med din fråga. Du använder LEFT JOIN, men du förvandlas till en implicit INNER JOIN med din where-klausul:AND (a.list_in='store' OR u.shop_active='1')
Varför gör detta LEFT JOIN till ett implicit INNER? Eftersom LEFT JOIN kommer att producera NULL-värden för u.shop_active när det inte finns någon matchande användare, men NULL kommer ALDRIG att vara lika med '1'. Detta förvandlar frågan till en INNER JOIN eftersom alla rader som produceras av OUTER JOIN kommer att filtreras av WHERE-villkoret.
Detta filter är också orsaken till prestandaproblemet. Du har ett ELLER-villkor mellan kolumner i två olika tabeller. Det finns inget index som kan uppfylla ett sådant villkor.
Här är ett annat sätt som kan fungera bättre. Den här versionen söker endast efter listor där (a.list_in !='store' och u.shop_active ='1') när det finns mindre än 12 list_in='store'-listor.
För att använda följande, se till att du har ett index på (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;