Pergunta

I am doing a sub-query join to another table as I wanted to be able to sort the results I got back with it, I only need the first row but I need them ordered in a certain way so I would get the lowest id.

I tried adding LIMIT 1 to this but then the full query returned 0 results; so now it has no limit and in the EXPLAIN I have two rows showing they are using the full 10k+ rows of the auction_media table.

I wrote it this way to avoid having to query the auction_media table for each row separately, but now I'm thinking that this way isn't that great if it has to use the whole auction_media table?

Which way is better? The way I have it or querying the auction_media table separately? ...or is there a better way!?

Here is the code:

SELECT 
    a.auction_id,
    a.name,
    media.media_url
FROM 
    auctions AS a 
    LEFT JOIN users AS u ON u.user_id=a.owner_id 
    INNER JOIN ( SELECT media_id,media_url,auction_id 
                         FROM auction_media 
                         WHERE media_type=1 
                          AND upload_in_progress=0 
                         ORDER BY media_id ASC
            ) AS media 
            ON a.auction_id=media.auction_id 
WHERE a.hpfeat=1 
  AND a.active=1 
  AND a.approved=1 
  AND a.closed=0 
  AND a.creation_in_progress=0 
  AND a.deleted=0 
  AND (a.list_in='auction' OR u.shop_active='1') 
GROUP BY a.auction_id;

Edit: Through my testing, using the above query seems like it would be the much faster method overall; however I worry if that will still be the case when the auction_media table grows to like 1M rows or something.

Foi útil?

Solução

edit: As stated in the comments - DISTINCT is not required because the auctions table can only be associated with (at most) one user table row and one row in the inner query.

You may want to try this. The outer query's GROUP BY is replaced with DISTINCT since you don't have any aggregate function. The inner query, was replaced by a query to find the smallest media_id per auction_id, then JOINed back to get the media_url. (Since I didn't know if the media_id and auction_id were a composite unique key, I used the same WHERE clause to help eliminate potential duplicates.)

SELECT
    a.auction_id,
    a.name,
    auction_media.media_url
FROM auctions AS a 
LEFT JOIN users AS u 
  ON u.user_id=a.owner_id 
INNER JOIN (SELECT auction_id, MIN(media_id) AS media_id
            FROM auction_media 
            WHERE media_type=1 
               AND upload_in_progress=0 
            GROUP BY auction_id) AS media 
  ON a.auction_id=media.auction_id 
INNER JOIN auction_media
  ON auction_media.media_id = media.media_id
    AND auction_media.auction_id = media.auction_id
    AND auction_media.media_type=1 
    AND auction_media.upload_in_progress=0 
WHERE a.hpfeat=1 
  AND a.active=1 
  AND a.approved=1 
  AND a.closed=0 
  AND a.creation_in_progress=0 
  AND a.deleted=0 
  AND (a.list_in='auction' OR u.shop_active='1');
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top