LEFT JOIN有多个表。表现不佳

时间:2016-09-13 20:53:46

标签: mysql performance left-join

我需要优化以下查询。表中有很多记录:a,b,c,d,查询时间很长。请求帮助。

SELECT main.*, items.*
FROM main
LEFT JOIN (
  (SELECT a.*, 1 AS `type` FROM a) UNION
  (SELECT b.*, 2 AS `type` FROM b) UNION
  (SELECT c.*, 3 AS `type` FROM c) UNION
  (SELECT d.*, 4 AS `type` FROM d)
)
items ON main.`to` = items.id AND main.`type` = items.`type`
WHERE main.id > 0
LIMIT 20

1 个答案:

答案 0 :(得分:0)

呸!像这样:

SELECT main.*, z.*
    FROM (
    ( SELECT  1 AS type, main.id AS mid, a.*, xx
        FROM  main
        JOIN  a  ON a.id = main.to
        WHERE  main.id > 0  AND main.type = 1
        ORDER BY  xx
        LIMIT  20 )
    UNION ALL
    ( SELECT  2 AS type, main.id, b.*, xx
        FROM  main
        JOIN  b  ON a.id = main.to
        WHERE  main.id > 0  AND main.type = 2
        ORDER BY  xx
        LIMIT  20 )
    UNION ALL
    ( SELECT  3 AS type, main.id, c.*, xx
        FROM  main
        JOIN  c  ON a.id = main.to
        WHERE  main.id > 0  AND main.type = 3
        ORDER BY  xx
        LIMIT  20 )
    UNION ALL
    ( SELECT  4 AS type, main.id, d.*, xx
        FROM  main
        JOIN  d  ON a.id = main.to
        WHERE  main.id > 0  AND main.type = 4
        ORDER BY  xx
        LIMIT  20 )
      ORDER BY xx
      LIMIT 20 ) z
    JOIN main  ON main.id = z.mid
ORDER BY xx;

Plus索引:

main: PRIMARY KEY(id), INDEX(type, xx, id, to)
a,b,c,d:  PRIMARY KEY(id)

注意:

  • 我假设你真的想按xx排序main
  • 我假设所有表格都有PRIMARY KEY(id)
  • main上的4-col索引在进行过滤和排序方面有所帮助;它是"覆盖"。
  • 6 ORDER BY + LIMIT将中间表最小化为80行。最后一个是因为子查询不需要保留顺序。
  • main.id > 0是一种痛苦 - 我们可以摆脱它吗?
  • 假设没有重复,
  • ALL而不是DISTINCT
  • SELECT *是一种痛苦;可以避免吗?由于它,我搞砸了确切的列列表。
  • JOIN返回main是为了避免牵引所有main.*;相反,只需要获取80个。