MySQL优化联接

时间:2019-04-11 15:00:34

标签: mysql join sql-optimization

我继承了以下查询:

    select [...]
    from
        t_bike_use
            join t_bike
                 on t_bike_use.bid = t_bike.id
            join t_user
                 on t_bike_use.uid = t_user.id
            left join t_violation
                      on t_violation.useid = t_bike_use.id
            left join t_trade
                      on t_bike_use.id = t_trade.record_id
            left join t_admin
                      on t_bike_use.admin_id = t_admin.id
            join t_user_detail
                 on t_user.id = t_user_detail.uid
    group by t_bike_use.id
    order by t_violation.id desc

我无法让此联接快速执行。当前,它花费1.6s,并且由于它经常执行,因此容易使数据库瘫痪。

t_bike_uset_biket_usert_trade表的行数均在2k至8k之间。但是,t_bike_uset_biket_user之间有外键,而t_trade.record_id没有外键。

如果我删除t_trade的联接,执行时间将降至400ms。

    left join t_trade
              on t_bike_use.id = t_trade.record_id

我在t_trade.record_id上有一个索引,但是MySQL 5.6不想使用它。

如何优化此查询?

这是EXPLAIN的输出。

1  SIMPLE  t_bike_use     ALL     PRIMARY,uuid,fk_uid,fk_bid  <>       <>  <>                   1771  Using temporary; Using filesort
1  SIMPLE  t_violation    ALL     <>                          <>       <>  <>                   1     Using where; Using join buffer (Block Nested Loop)
1  SIMPLE  t_user         eq_ref  PRIMARY                     PRIMARY  4   t_bike_use.uid       1   
1  SIMPLE  t_bike         eq_ref  PRIMARY                     PRIMARY  4   t_bike_use.bid       1   
1  SIMPLE  t_user_detail  ref     fk_uid                      fk_uid   4   t_bike_use.uid       1   
1  SIMPLE  t_trade        ALL     record_id                   <>       <>  <>                   2085  Range checked for each record (index map: 0x2)
1  SIMPLE  t_admin        eq_ref  PRIMARY                     PRIMARY  4   t_bike_use.admin_id  1   

1 个答案:

答案 0 :(得分:-1)

您可以使用子查询来代替Join,这样可以更快地执行查询。