写这个查询的最佳方法是什么?

时间:2014-03-11 18:40:42

标签: mysql join subquery query-optimization inner-join

我正在对另一个表进行子查询连接,因为我希望能够对我得到的结果进行排序,我只需要第一行,但我需要它们以某种方式排序,所以我会得到最低的身份。

我尝试将LIMIT 1添加到此,但完整查询返回0结果;所以现在它没有限制,在EXPLAIN我有两行显示他们正在使用auction_media表的完整10k +行。

我这样编写它是为了避免分别查询每一行的auction_media表,但现在我认为如果必须使用整个auction_media表,这种方式不是很好吗? / p>

哪种方式更好?我有它的方式或单独查询auction_media表? ......还是有更好的方法!?

以下是代码:

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;

编辑:通过我的测试,使用上面的查询似乎总体上要快得多;但是我担心,当auction_media表增长到1M行或类似内容时,情况仍然如此。

1 个答案:

答案 0 :(得分:2)

编辑:如评论中所述 - DISTINCT不是必需的,因为拍卖表只能与(最多)一个用户表行和内部查询中的一行相关联。

您可能想尝试一下。 外部查询的GROUP BY被替换为DISTINCT,因为你没有任何聚合函数。内部查询被查询替换为每个auction_id找到最小的media_id,然后加入了获取media_url。 (因为我不知道media_id和auction_id是否是复合唯一键,所以我使用相同的WHERE子句来帮助消除潜在的重复。)

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');