后端存储实战课
李玥
美团高级技术专家
44005 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语 (1讲)
后端存储实战课
15
15
1.0x
00:00/00:00
登录|注册

09 | 怎么能避免写出慢SQL?

key列:实际使用的索引
type列:查询的访问类型
rows列:预估遍历的数据行数
查询多更新少表多建索引
更新频繁表少建索引
降低数据插入、删除和更新性能
数据结构:B树和HASH表
数据库索引类似于Map或Dictionary
估算查询需要遍历的数据行数
遍历的数据行数
实际TPS需打折扣
服务器配置影响
每秒一万条左右的简单SQL
数据库繁忙程度
MySQL参数配置
数据库数据量大小
服务器配置
执行计划分析
EXPLAIN关键字
增加索引的代价
索引原理
SQL执行时长的衡量
MySQL处理能力的极限
影响MySQL处理能力的因素
为什么第一个SQL没有使用索引?
分析SQL执行计划
使用索引避免全表扫描
定量认识MySQL
思考题
怎么能避免写出慢SQL?

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
通过上节课的案例,我们知道,一个慢 SQL 就可以直接让 MySQL 瘫痪。今天这节课,我们一起看一下,怎么才能避免写出危害数据库的慢 SQL。
所谓慢 SQL,就是执行特别慢的 SQL 语句。什么样的 SQL 语句是慢 SQL?多慢才算是慢 SQL?并没有一个非常明确的标准或者说是界限。但并不是说,我们就很难区分正常的 SQL 和慢 SQL,在大多数实际的系统中,慢 SQL 消耗掉的数据库资源,往往是正常 SQL 的几倍、几十倍甚至几百倍,所以还是非常容易区分的。
但问题是,我们不能等着系统上线,慢 SQL 吃光数据库资源之后,再找出慢 SQL 来改进,那样就晚了。那么,怎样才能在开发阶段尽量避免写出慢 SQL 呢?

定量认识 MySQL

我们回顾一下上节课的案例,那个系统第一次全站宕机发生在圣诞节平安夜,故障之前的一段时间,系统并没有更新过版本,这个时候,其实慢 SQL 已经存在了,直到平安夜那天,访问量的峰值比平时增加一些,正是增加的这部分访问量,引发了数据库的雪崩。
这说明,慢 SQL 对数据库的影响,是一个量变到质变的过程,对“量”的把握,就很重要。作为一个合格的程序员,你需要对数据库的能力,有一个定量的认识。
影响 MySQL 处理能力的因素很多,比如:服务器的配置、数据库中的数据量大小、MySQL 的一些参数配置、数据库的繁忙程度等等。但是,通常情况下,这些因素对于 MySQL 性能和处理能力影响范围,大概在几倍的性能差距。所以,我们不需要精确的性能数据,只要掌握一个大致的量级,就足够指导我们的开发工作了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了如何避免编写慢SQL的方法,从定量认识MySQL、使用索引避免全表扫描和分析SQL执行计划三个方面展开。首先,强调了对数据库处理能力的定量认识的重要性,提出了MySQL处理能力的极限和慢SQL的衡量标准。其次,介绍了使用索引来避免全表扫描的原理和方法,并指出了增加索引可能带来的性能代价。最后,通过分析SQL执行计划的方法,读者可以了解查询性能如何,以及如何优化查询语句。这些方法对于开发人员在开发阶段尽量避免写出慢SQL具有重要的指导意义。文章提供了衡量SQL查询性能的手段,强调了控制数据表行数和使用索引的重要性,同时也指出了索引可能带来的性能影响。此外,通过使用SQL执行计划进行查询优化,读者可以更好地了解查询语句的性能表现。整体而言,本文为读者提供了全面的避免慢SQL的方法和技巧,对于开发人员和数据库管理员具有实际指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端存储实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(43)

  • 最新
  • 精选
  • 冯玉鹏
    innodb 的索引是用索引关联列以b+树的形式 管理,其中主键索性和数据的物理顺序一致,也叫聚集索引。非主键索引实际上是指向主键索引。 文末的问题对 department_code 列 left 运算后,MySQL 认为运算后的结果不可与原数据列内容匹配,故采用全表扫描, 而第二个语句like '00028%' 可以使用到索引 是因为索引的最左匹配选择,如果%在前面也将无法使用索引。PS:在这里MySQL的查询优化器在使用了left函数无法匹配索引可以认为有偷懒的嫌疑,哈哈~ 类似的场景还有 where 列 +1 = val 查询优化器也完全可以改写成 where 列=val - 1。

    作者回复: 👍👍👍

    2020-03-17
    7
    81
  • Regis
    后台实际开发中,使用ORM的框架的情况是不是很多?如果使用ORM框架,SQL的写法就不可控了。实际开发中是使用ORM框架好还是直接书写SQL好?还是两种都会存在?一些复杂的查询使用框架查询感觉很痛苦

    作者回复: 我的建议是,在线交易类系统(OLTP,大部分服务业务的CRUD类系统)使用ORM框架。 分析类系统(OLAP,各种分析和报表类系统)直接写SQL。

    2020-03-18
    3
    23
  • 贾敏
    只知道 LIKE '00028%' 会使用索引, 但是为什么说是最左匹配呢?谢谢老师

    作者回复: 你想一下B+树的结构是什么样的,就会明白了。

    2020-04-09
    2
    14
  • 我好像一点都不像程序员
    单表数据量尽量不要超过千万级别,可以采取的措施有水平分表和垂直分表,在报表数据统计相关的业务中,主要采取的是水平分表,按天,按月,甚至是按日,也有分区,但是这些存储的优化方案,给编码造成了一定的难度,目前我接触的数据表基本都是千万级别,有的甚至过亿,大多是业务日志表,说实话,除了统计所需要的中间表,日志表和页面展示相关的表我们都没有进行分表,我挺想知道我这种架构应该怎么去调整比较好

    作者回复: 请 继续往下学习,我们的课程后面有大量的篇幅来讲,如何解决你提出的问题。

    2020-06-20
    3
  • LiG❄️
    老师,想请教您一个问题:mysql单库表数量有限制吗?每个库多少表会比较合适啊?ps:项目中设计一个消息推送系统,消息存储现在是以人分表,一人一个消息表(会造成表数据膨胀);还有想法是想重构,把消息都存在一起,以时间分表~没有做过大存储,还望老师指教😄

    作者回复: 我会在《15 | MySQL存储海量数据的最后一招:分库分表》这节课来讲分库分表的问题。

    2020-03-26
    2
  • 呦呦鹿鸣
    李老师好,一直有个疑问,评估数据量时一般只考虑数据行数就可以么?相同行数下的两张表,2个字段跟20个字段的性能差异需要如何评估呢?

    作者回复: 列的数量是会影响查询性能的,但相比行数的影响要小得多,所以,如果不是列特别多的情况,可以忽略这个影响。

    2020-04-14
    1
  • 特种流氓
    老师 能否在mysql中做设置 超时的sql查询自动停止执行

    作者回复: 据我所知,MySQL还没有这个功能。

    2020-03-25
    3
    1
  • fgdgtz
    你好老师,我想问问如果是 order by 多个字段排序的执行流程是什么样的呢? 比如 有40000行 order by a desc,b desc limit 1000 ,a字段有索引,b字段无索引,a字段保存的是时间戳,有少部分时间戳是同样的,此时explain 会有 Using filesort,这样放入sort_buffer 是40000行 还是 大于1000行而小于40000行呢?或是扫描了多少行?

    作者回复: 你可以把SQL和执行计划贴出来我们一起讨论。

    2020-03-21
    3
    1
  • 小袁
    简单来说,要写成 "索引 列 = 计算表达式"这种形式,养成这个习惯
    2020-03-17
    1
    30
  • leslie
    原因很简单:函数破坏了索引,其实这种写法基本上都会在程序端禁止的;code review这关过不去的,直接发回开发-重写。like 语句其实用到了mysql 5.7所引用的特性 分列,问题就这么简单。
    2020-03-25
    15
收起评论
显示
设置
留言
43
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部