繁体   English   中英

如果多个OR条件,则mysql加入性能

[英]mysql join performance IF multiple OR conditions

我在一个mysql table1中拥有一组节点,在另一个mysql table1中拥有一个边缘表(table2)。 节点带有主键,边缘使用此“外键”

**table1**
id label
1  node1
2  node2
3  node3

**table2**
FK_first FK_sec   rel
1        3        guardian
2        1        guardian
1        3        times

我知道数据库设计不是完美的,但是它很简单...现在,我想要每个节点的“ rel”数并执行如下查询:

SELECT 
  label, 
  COUNT( rel ) as freq
FROM
  `table1` 
  LEFT JOIN table2 ON (id=FK_first OR id=FK_second) 
GROUP BY label
ORDER BY freq DESC

我大约有1000个节点和2000个边缘。 查询为ON(id = FK_first 或id = FK_second ),则查询速度更快(<1秒)。 其他查询大约需要6秒钟,这非常慢。 我希望一些评论可以加快速度:-)

  1. LEFT JOIN table2 ON(id = FK_first或id = FK_second)〜6秒
  2. LEFT JOIN table2 ON(id = FK_first)〜0.16秒
  3. LEFT JOIN table2 ON(id = FK_second)〜0.16秒

  4. LEFT JOIN table2 ON id IN(FK_first,FK_second)〜6秒

EXPLAIN 1:
        id  select_type table   type    possible_keys                   key key_len ref rows    Extra
        1   SIMPLE          table1  ALL NULL                            NULL    NULL    NULL    2571    Using temporary; Using filesort
        1   SIMPLE          table2  ALL FK_first,FK_second,FK_first_2   NULL    NULL    NULL    3858    

EXPLAIN 2:
id  select_type  table  type   possible_keys       key    key_len ref        rows   Extra
1   SIMPLE       table1 index  NULL                PRIMARY    2   NULL       2571   Using index; Using temporary; Using filesort
1   SIMPLE       table2 ref   FK_first,FK_first_2  FK_first_2 4   table1.id  1

尝试进行两次联接并将“ OR”移到COUNT()函数中:

对于每一行,这会在FK1上一次联接table2,然后在FK2上再次联接(如果尚未通过FK1联接到该行。那么在COUNT中,我们指定只有联接的rel列为非空的行)。

SELECT 
  label, 
  COUNT( table2A.rel || table2B.rel ) as freq
FROM
  `table1` 
  LEFT JOIN 
    table2 as table2A 
    ON id=table2A.FK_first
  LEFT JOIN 
    table2 as table2B 
    ON id=table2B.FK_second 
    AND  table2A.FKFirst != table2B.FKFirst
GROUP BY label
ORDER BY freq DESC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM