美文网首页
血的教训-记一次Mysql线上事故

血的教训-记一次Mysql线上事故

作者: 10xjzheng | 来源:发表于2019-08-18 10:38 被阅读0次

昨天真是个悲伤的日子,背了来公司的第一个事故。
事故的根本原因是改动了一个查询条件,用了not in,导致无法命中排序索引,因为线上有个租户表数据有400w+,查询缓慢继而引发Mysql连接数撑爆了实例的CPU。

SQL:

SELECT
    `clue_csts`.`confirm_status`,
    `clue_csts`.`lose_type_id`,
    `b_broker_recommend`.`b_broker_recommendId`,
    `c`.`cst_name`,
    `b_broker_recommend`.`proj_id`,
    `b_broker_recommend`.`cst_id`,
    `c`.`mobile_tel`,
    `b_broker_recommend`.`last_report_time`,
    `b_broker_recommend`.`check_date`,
    `stage_id`,
    `is_delay`,
    `c`.`tel2`,
    `c`.`tel3`,
    `c`.`tel4`,
    `c`.`gender`
FROM
    `b_broker_recommend`
LEFT JOIN `b_broker_recommend_cst` `c` ON c.b_broker_recommend_cstId = b_broker_recommend.cst_id
LEFT JOIN `clue_csts` ON clue_csts.clue_cst_id = b_broker_recommend.clueId
WHERE
    `b_broker_recommend`.`regbroker_id` = '39ec911a-495a-3357-7e18-1a5c9e15279a'
AND b_broker_recommend.stage_id = '2'
AND (
    `c`.`mobile_tel` LIKE '%/+//Um9S5ErCikwXE4dXrWnuEg==/+//uuEySqVtmoCnOoPk9aV1fw==/+//GJg0MA+Q+xqQIknWJPJ8Nw==%'
    OR `c`.`tel2` LIKE '%/+//Um9S5ErCikwXE4dXrWnuEg==/+//uuEySqVtmoCnOoPk9aV1fw==/+//GJg0MA+Q+xqQIknWJPJ8Nw==%'
    OR `c`.`tel3` LIKE '%/+//Um9S5ErCikwXE4dXrWnuEg==/+//uuEySqVtmoCnOoPk9aV1fw==/+//GJg0MA+Q+xqQIknWJPJ8Nw==%'
    OR `c`.`tel4` LIKE '%/+//Um9S5ErCikwXE4dXrWnuEg==/+//uuEySqVtmoCnOoPk9aV1fw==/+//GJg0MA+Q+xqQIknWJPJ8Nw==%'
    OR `c`.`cst_name` LIKE '%13858616853%'
)
AND `b_broker_recommend`.`b_broker_recommendId` NOT IN (
    '39ec911d-1d24-6c6b-19cf-d4f90c34ec79',
    '39ed2864-8169-cec1-0391-51d8681500ec',
    '39ed7559-3889-6b8a-a977-835902f4dbbc',
    '39ede0e4-6baf-4e6e-11b8-789c285a8b0c',
    '39ede123-d7ab-6591-6a36-70791bf62a78',
    '39ee24b3-71f6-e4d1-a5b1-7bbfd16cd1de'
)
ORDER BY    `b_broker_recommend`.`check_date` DESC
LIMIT 20;

部分表名、字段名已被我替换掉。
索引是:
用来排序的符合索引:IX_regbroker_id,check_date (regbroker_id,check_date)。
explain:


image.png

从key那行可以看出排序索引是没有用到的,在check_date上对百万千万级别的数据进行排序之后再根据过滤条件来过滤,还有like和or,就死了,遇上not in比较多的这个sql要执行几十秒,并发连接一起来,死了,cpu就撑爆了,一大堆别的sql在等待执行。整个实例就挂了。


image.png
但我把not in里面的减少到两个,发现索引又用上了:
image.png
1s执行完。
3个以上就又不走了。

后来是又改成了连表进行过滤。这里就不贴SQL了。

结论:

  1. 慎用not in,特别是里面的枚举值多的情况,尽量不用,因为not in前面的字段是主键的缘故(多次测试),此条件会影响mysql的执行计划,其它表的字段虽然用了 like,or,但它依然会在索引上过滤并排序后进行过滤。
  2. 改变了sql的查询条件,特别是sql关联的表是大表,需要对多种场景进行explain,尽量防患于未然。

相关文章

  • 血的教训-记一次Mysql线上事故

    昨天真是个悲伤的日子,背了来公司的第一个事故。事故的根本原因是改动了一个查询条件,用了not in,导致无法命中排...

  • 记一次线上事故

    今天服务忽然炸了,log没有记录,服务一直重启导致数据库压力暴增。

  • Spring+SpringMVC+MyBatis+easyUI整

    前文提要 承接前文《一次线上Mysql数据库崩溃事故的记录》,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇...

  • 人生的价值

    最近工作单位频发安全事故,昨天下午又有发生一起工亡事故,这样的工亡事故每年都会有,看到一次次血的教训,说内心话,我...

  • 记一次线上'事故'处理

    记一次线上'事故'处理 今早十点左右(2019年12月23日 10:00), 项目运营反馈新版 App 有闪退问题...

  • 笔记20 关于开车的意识升级

    今天在高速路上,见证了一次血的教训。事故是怎么发生的不清楚,只知道今天一直下雪,小车和运集装箱的拖挂车发生了事故,...

  • 事故猛于虎,牢记血的教训

    时间回到2017年夏天,那天正好是我生日。儿子跟爷爷奶奶回农村老家去了,就我跟老婆在成都。这原本是平平静静的一天,...

  • 一次线上MySQL分页事故,搞了半夜...

    目录 背景 分析 数据模拟 测试 解决方案 小结 今天给大家分享个生产事故,一个由于 MySQL 分页导致的线上事...

  • iOS-clang: error: no such file o

    这一篇没什么技术含量,记一次血的教训 执行‘pod install’的时候遇到个错误如图,然后把`$(inheri...

  • 记一次线上事故的复盘

    背景 上周周四0点上线的一个新功能,7点半本人发现有问题,知会产品及时调整策略。事故造成的影响为重复发奖了10笔,...

网友评论

      本文标题:血的教训-记一次Mysql线上事故

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