2013-02-21 80 views
0

布告牌表140000行,地区1000行。或左连接

SELECT 
    r.id, 
    SUM(IF(bb.r1_id = r.id, 1, 0)) AS count, 
    SUM(IF(bb.r2_id = r.id, 1, 0)) AS count2 
FROM 
    tmp_regions AS r 
LEFT JOIN 
    tmp_billboards AS bb 
    ON (r.id = bb.r1_id OR r.id = bb.r2_id) 
WHERE 
    bb.deleted = 0 
    AND 
    bb.x != 0 
    AND 
    bb.y != 0 
GROUP BY r.id 
ORDER BY r.capital DESC , r.other , r.name 

执行时间为8秒

解释

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE bb ref bb_r,bb_deleted,bb_x,bb_y,deleted_x_y,bb_r2 bb_deleted 1 const 66396 Using where; Using temporary; Using filesort 
1 SIMPLE r ALL PRIMARY NULL NULL NULL 1000 Using where; Using join buffer 

我怎样才能改变或加入以提高演出内容吗?

+0

首先,将'LEFT'连接改为内连接。 – 2013-02-21 07:25:38

+0

我做了:执行时间〜6.8 - 7秒。同样解释输出 – Mikhail 2013-02-21 07:30:28

回答

0

假设tmp_regions (id)是主键,你可以重写查询和OR转换为2联接:

SELECT 
    r.id, 
    COALESCE(bb1.cnt, 0) AS count, 
    COALESCE(bb2.cnt, 0) AS count2 
FROM 
    tmp_regions AS r 
    LEFT JOIN 
    (SELECT r1_id, COUNT(*) AS cnt 
     FROM tmp_billboards 
     WHERE deleted = 0 
     AND x <> 0 
     AND y <> 0 
     GROUP BY r1_id 
    ) AS bb1 
    ON r.id = bb1.r1_id 
    LEFT JOIN 
    (SELECT r2_id, COUNT(*) AS cnt 
     FROM tmp_billboards 
     WHERE deleted = 0 
     AND x <> 0 
     AND y <> 0 
     GROUP BY r2_id 
    ) AS bb2 
    ON r.id = bb2.r2_id 
ORDER BY r.capital DESC , r.other , r.name ; 

为了提高效率,在(deleted, r1_id, x, y)(deleted, r2_id, x, y)指标将有助于避免在tmp_billboards表扫描。

+0

>> ypercube非常感谢!有用! – Mikhail 2013-02-21 07:55:14

0

添加索引。 explain的输出显示哪些字段需要它们。