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

パフォーマンスを向上させるために結合で OR を変更するにはどうすればよいですか?

4

2 に答える 2

1

インデックスを追加します。の出力は、explainそれらが必要なフィールドを示します。

于 2013-02-21T07:38:13.720 に答える
0

それが主キーであると仮定するとtmp_regions (id)、クエリを書き直すことができ、OR2 つの結合に変換されます。

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

于 2013-02-21T07:41:22.410 に答える