美文网首页
记一次MySQL子查询in不走索引优化

记一次MySQL子查询in不走索引优化

作者: 神易风 | 来源:发表于2021-09-26 23:23 被阅读0次

    最近在项目里面将Druid的SQL监控打开,发现了一个慢SQL查询,单表查询数据只有几万条,执行数据居然要2s,SQL如下

    SELECT * FROM instance_metric WHERE id in (select min(id) from instance_metric GROUP BY code )

    explain分析SQL

    看起来没什么问题,子查询过滤出重复记录,返回最小id ,in 后面接入的是id,数据很快才对的啊。使用explain 分析执行过程,结果大失所望

    id select_type table partitions type possible_keys key key_len ref rows filtered Extra
    1 PRIMARY instance_metric NULL ALL NULL NULL NULL NULL 619621 100.00 Using where
    2 SUBQUERY instance_metric NULL ALL NULL NULL NULL NULL 619621 100.00 Using temporary

    可以看出in 后面并没有走索引查询,走了全表扫描,很纳闷。

    正常in接参数

    直接使用id 放入in 括号中

    EXPLAIN select * from instance_metric WHERE id in (1,2,3);

    id select_type table partitions type possible_keys key key_len ref rows filtered Extra
    1 SIMPLE instance_metric NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where

    执行结果没问题的,查询是走索引的

    使用表关联代替in

    本来想着使用exists代替in 使用,发现exists好像写不出来,不知道怎么取到最大值、最小值比较。当没有办法时,冷静来想想使用id来过滤重复记录,为什么不使用表关联呢,我的是个天才啊😀。

    EXPLAIN select i.* from instance_metric i inner JOIN (select min(id) id from instance_metric GROUP BY code ) t1 on t1.id = i.id

    id select_type table partitions type possible_keys key key_len ref rows filtered Extra
    1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 10 100.00 Using where
    1 PRIMARY i NULL eq_ref PRIMARY PRIMARY 4 t1.id 1 100.00 NULL
    2 DERIVED instance_metric NULL ALL NULL NULL NULL NULL 10 100.00 Using temporary

    可以看到内表关联是走索引的,搞定。

    相关文章

      网友评论

          本文标题:记一次MySQL子查询in不走索引优化

          本文链接:https://www.haomeiwen.com/subject/sfrngltx.html