帮同事排查1个接口问题,测试环境是好的,响应0.1s,到线上忽然响应成4s了。 没有远程rpc调用,所以不会所谓超时3s。 看了下逻辑,就是单纯的查sql。 于是我拿sql查了下线上数据,发现确实需要3,4s。
sql很复杂,十几张表联查,我只能一个个删减联的表,最后发现删掉某个连的表时候速度响应为0.1s了。 于是单独只联这张表,发现响应就为3s了。 sql类似于:
SELECT
u1.id,u2.name loveUserName
FROM
user u1
LEFT JOIN user u2 ON u2.love_uid = u1.id
sql不难,其实就是继续关联同1个表查某一个字段而已,我一开始以为是其他表数据量大的问题,没想到是这简单的1个sql竟然查需要3,4s,而且数据量只有几千。
explain分析了下是这样的:
Using join buffer (Block Nested Loop)这个错误倒是第一次见到,百度到说可能是没有加索引但是我show index from user了之后发现是有索引的。
最后发现是sql写错了!
改成:
SELECT
u1.id,u2.name loveUserName
FROM
user u1
LEFT JOIN user u2 ON u2.id = u1.love_uid
有点无语,我菜,女同事更菜.。
但也记录下吧。
Using join buffer (Block Nested Loop)这个错误也可以是 join 的on条件写错了导致。
仔细想想也确实,2条数据 (1,2) (2,null) 如果写反了确实感觉mysql要遍历多次了,复杂度上升1个级别。
测试环境几百条好的很,几千条则不行了。