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尽量避免子查询,改用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慢查询...

    大表做分页查询时,应该把 limit a,b 改成 where id > n limit b.   原因:当a的值很大时,会扫描很多行导致sql很慢;记录上一次查询到数据的id,然后用where id > n,能减少扫描的行数。

 

 

ALTER TABLE vord_worksheet MODIFY  ext varchar(2048)  CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci not NULL default '' COMMENT 'ext';
 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值