MySQL 运维实战课
张新铭(俊达)
云掣科技资深数据库专家,前淘宝网、支付宝数据库专家
886 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已更新 26 讲/共 41 讲
MySQL 运维实战课
15
15
1.0x
00:00/00:00
登录|注册

24|10+ SQL执行性能不佳的真实案例(下)

你好,我是俊达。这节课我们继续看剩下的几个案例。

案例七:优化 or 查询的另一个例子

下面是另一个在 where 中使用了 or 的例子,这个 SQL 的性能非常差,需要将 3 个表的数据全部关联起来。
SELECT t_msg.msg_id,t_msg.content , ......
FROM t_msg
LEFT JOIN t_user ON t_msg.user_id = t_user.user_id
LEFT JOIN t_group ON t_msg.group_id = t_group.group_id
WHERE t_msg.gmt_modified >= date_sub('2018-05-20 09:31:45', INTERVAL 30 SECOND)
OR t_user.gmt_modified >= date_sub('2018-05-20 09:31:45', INTERVAL 30 SECOND)
OR t_group.gmt_modified >= date_sub('2018-05-20 09:31:45', INTERVAL 30 SECOND)
业务的需求,是查询最近半分钟内发生过变化的数据。这个 SQL 的 where 条件中,用到了 3 个表的 gmt_modified 字段来过滤数据,而且这些条件使用 or 相连。看一下下面的示意图,业务关心的是新数据,每个表中,最近修改过的数据都只占了整个表数据的一小部分。而且 t_user、t_group 表的数据很少更新。但由于 SQL 的写法,每次都需要连接全量的数据,然后再过滤出一小部分数据,因此 SQL 的效率很低。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
  • 解释
  • 总结

1. 拆分复杂SQL语句可以提高查询效率,让优化器选择更好的执行计划。 2. MySQL 8.0之前版本不支持自动转换exists子查询为半连接,手动改写SQL可以提升性能。 3. 优化器在计算REF和Range的访问成本时,有时会选择REF访问路径而不是效率更高的Range。 4. 使用force index提示可以改变执行计划类型,提高查询效率。 5. 当IN参数列表过长时,可能导致全表扫描,可以通过调整索引字段顺序或调整参数来解决。 6. 数据倾斜可能导致连接时扫描的记录数增加,需要业务方进行处理。 7. "Range checked for each record"是一个查询性能不好的信号,可以尝试优化SQL。 8. 优化SQL逻辑、使用MySQL 8.0的窗口函数等方法可以提升查询性能.

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

全部留言(1)

  • 最新
  • 精选
  • 叶明
    1、对 SQL 性能的影响,t1.s1 和 t2.s2 这两个字段来源不同表,并且没有关联关系,驱动表只有一个,当其中一个字段有序时,无法保证另一个字段也有序,因此必须使用到临时表和文件排序,另外如果数据量较大,则还会使用到更慢的磁盘临时表来处理。 2、如果只使用一个表的字段来排序,性能上会有什么区别吗?如果表上这一个用来排序的字段上有索引,那么以这个表作为驱动表,一来不用建立临时表和排序,只需要有序遍历这个索引的前 100条记录就可以返回了,二来只用返回 100 条数据,大大减少了扫描行数
    2024-10-16归属地:江苏
收起评论
显示
设置
留言
1
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部