mysql的子查询、内连接/外连接、笛卡尔积

——纪念一次mysql子查询打满CPU...

sql原文大致如下:
    select * from A where id in (select B.a from B where B.b in (select C.a from C where C.b = ?))

    涉及到的查询字段都有索引,但是由于mysql对子查询的优化做的不好,查询引擎对于子查询很容易选错合适的索引,导致在线上实际跑的时候,外侧的大表A没有走到id字段的主键索引,导致访问类型type=ALL遍历全表,检索了2KW行数据,把cpu拉满了。。

 生产实际执行sql的explain详情:mysql的子查询、内连接/外连接、笛卡尔积

    总结:改掉随手写子查询的陋习。。mysql尽量避免子查询,改用join方式(或者exist,不过感觉exist不好阅读)可以避免此类问题。

 

查这个问题时看到的相关文章:

    1.遇到同样问题的老哥:https://blog.csdn.net/kevinxxw/article/details/88718663

    2.mysql explain详解:https://www.cnblogs.com/tufujie/p/9413852.html

    3.mysql 内外连接相关:https://blog.csdn.net/qq_40086556/article/details/81807849

    4.深入理解MySql子查询IN的执行和优化:https://blog.csdn.net/lppl010_/article/details/79890050

    5.mysql表连接相当于做了笛卡尔积,使用 join xxx on xxx 方式可以优化,结果是局部笛卡尔积 (ON语句的执行是在JOIN语句之前的,也就是说两张表数据行之间进行匹配的时候,会先判断数据行是否符合ON语句后面的条件,再决定是否JOIN)

    6.mysql 内连接/左连接会出现笛卡尔积?   https://blog.csdn.net/zy_281870667/article/details/81046573

 

sql执行顺序:

 mysql的子查询、内连接/外连接、笛卡尔积