【七天深入MySQL实战营】答疑汇总Day4 MySQL查询优化实战

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 【开营第四课】【 MySQL查询优化实战】讲师:苏坡,袋鼠云高级数据库工程师。课程内容:核心概念及原理;优化流程思路;常见场景下的优化。答疑汇总:特别感谢班委@李敏 同学

【开营第四课】【 MySQL查询优化实战】
讲师:苏坡,袋鼠云高级数据库工程师。
课程内容:核心概念及原理;优化流程思路;常见场景下的优化。
答疑汇总:特别感谢班委@李敏 同学

1. 除了 explain,会有好的办法调优 sql 吗?

观测 mysql 行为的方法主要有两种:

1) explain sql 语句

(2)show processlist 详情见 ppt 22 页(查看当前活跃会话状态)

调优 sql 的方法还有两种:

(1)show profiles,一条 sql 语句执行过程当中,每一步的开销

(2) Sql 优化器的 trace,可以看到优化器在选择执行计划时的判断标准,分析 sql 的时候,需要临时开一下,帮我们去模拟生成执行计划的过程(参考 https://segmentfault.com/a/1190000018136007

2.之前一直用 sqlserver,如果一个表 tbl,有 A、B 两个字段,且每个字段都建有一个索引,当执行 select * from tbl where A=? And B=? 时,mysql 会同时使用这两个索引查,然后将两个结果合并?

A:索引合并,是 innodb 优化器的一个比较典型的特征,通常来讲,发现一个sql语句出现索引合并的话,表示sql语句性能并不好,索引合并举例:and 交集,or 并集,一般来说一个表里面,建立了太多单列索引,就可能出现这种情况(索引合并)。看到(sql 语句)走的 a 和 b 两个索引,并且取的是交集,说明单个索引的过滤性并不是很好,建议改造成复合索引,建议大家一定要定期去检查表当中的索引,不要有太多单个的索引。

3.对于 8.0 的 explain analyze 有什么看法?8.0 的 hash join 之类的很多新特性,越来越接近 oracle,(老师)对于 mysql 的发展有什么看法?

A:8.0 的这个工具特别好用,推荐大家去使用,相比 5.6 和 5.7 的 analyze,8.0 的工具去分析问题的话,更为精确一些;不敢妄下结论,mysql毕竟从一个数据仓库的产品发展到现在,被收购 oracle 之后,oracle 的特性,在各个方面确实是比较完善一些,但 mysql 也并不是完全在接近 oracle,是在汲取 oracle 的一些特性吧。

4.Centos 下 Mysql 内存使用 1 个月内缓慢增长,直至数据库 OOM,kill 连接也不会释放,Mysql 内存参数已做限制,请问如何配置有效自动释放内存,个人查到 centos 内存调度算法 malloc 可以优化,但未实践(老师)在日常的工作上,也有碰到过内存相关的问题,做一些内存分析的工作之前,首先还是要看 mysql 是什么版本的,5.7 以前,分析内存可做的事情有限,比如分析数据库的会话和sql,推测某些操作会带来内存迅速升高,单从 mysql 的行为来去看(,不太好判断),5.7 之后,可以通过开启性能视图来分析,5.7 的性能视图还是比较丰富的,特别是内存这一块,建议感兴趣的同学可以去研究研究。

5.应用有两个数据源,一个是 mysql 8;一个是 mysql 5.7,用 8 版本的 jar 会对 5.7 的数据源有什么影响吗?这个应用在服务器的 tomcat 上部署旧报链接不上 mysql 8 的数据源,本地测试就可以,具体可以往那方面排查?

A:这个要不看一下 jdbc 版本的问题,关于连不上数据库的话,可能会报不同的原因,这个要有不同的报错出来(主要观察是报错内容,然后具体错误具体分析)。

6.select * from jdp_tb_trade where seller_nick in (‘’,’’,’’,’’...)。当 in 的集合中数量超过 9 后,会切换索引,导致查询变慢。这是什么原因,得怎么优化?

A:n 数量太多切换索引,这个是比较正常的的,要看切换前后具体使用什么索引。in 集合元素的数量,导致优化器选择了不同的索引,可以看看 where 条件的字段是不是够好的。关于这种问题,如何分析,首先看一下这个表有没有索引,在分析一下在(?)字段上数据分布的规律。(优化方式老师没回答,在 sql 语句中使用 use index ,可以强制指定索引)

7.数据库达到什么条件时才应该考虑分库分表

A:问题很实在,总会听到各种各种的看法,比如表达到多少条数据,或者怎么样之后。从我的角度来看,我们先优化,从下往上,sql及索引、库表结构、系统配置配置(详见 PPT第 6 页)、硬件,这是吹着调优的的过程,把单一 mysql 实例变得更好的过程,如果垂直调优达到瓶颈,当单个 mysql 已经做得足够好的情况下,我们要考虑分库分表。还有一种情况,在某些业务场景中,我们的业务压力,在将来特别短暂的一段时间可能会有扩增,对于业务发展情况,为了应对用户量、访问量的膨胀,提前考虑分库分表的策略。

8.新业务需要添加字段,如果该业务下线。如果多次的话,会有很多的无用字段,这种情况要怎么处理比较好?

A:业务上下线,需要增加/删除字段,这种做法并不不建议,在生产环境,频繁的给 mysql 表,增加/删除字段。某些企业情况特殊,确实需要频繁变动,像这种情况,可以考虑使用一下 mongodb 数据库,还有一种方式(在表里面)增加一种扩展的字段,没有就是空,有就塞(默认为空,在必要的时候才填充),这种也不太建议。

9.当业务开发时发现需要频繁获取分库后的某个库里的数据,应该通过 rpc 调用其他连接该库的 java 服务来获取,还是应该考虑重新分库?

第9个问题没有看太明白

10.请问循环事务调用的场景下,怎么在正常请求下保证强一致性?

有些问题信息不是很完善,以后私下沟通交流

11.请问如何通过网络层面分析是某些 sql 占用了大量的网络带宽?

A:网络带宽,可以通过有一些诊断工具/平台去分析,当有一个比较好的监控体系之后,看到在某个时间段,有网络带宽的上涨,首先判断是 出/入==> 查询/插入,通常来讲,像网络层面的增加,是查询,看到这种现象,然后分析对应的时间段,哪些 sql 语句扫描/返回的行数比较高,一般情况来讲的话,关于网络带宽升高的情况,某些查询返回大量数据,再去分析某个时间段,sql 的统计情况,就可以了。

12.对非时间字段建 hash 分区,有什么最佳推荐?

A:对于 hash 的话,并不是十分推荐,hash 这种算法只是单纯将数据打散,还是要看具体的查询场景,如果字段是枚举型的,比如分类,像电商场景下,(字段)是一个比较大的组织的 id / 地区,如果查询里面,都会携带这个 id,那我们就按照这个字段去分区,也是可以允许的

13.表分区个数有限制吗?有上万张表,按天分区能行吗?

A:表分区限制肯定有,具体数值一时说不上来,需要查看文档

14.mysql 存储过程功能和 oracle 存储过程相比有什么缺点?之前的一个培训老师说不建议使用 mysql 存储过程时什么原因?

A:为什么在 mysql 里面不建议使用,首先要清楚认识存储过程是一个什么东西:在数据库里面运行的,一段业务计算逻辑,属于业务代码,运行(业务代码)需要消耗额外的计算资源。msyql 和 oracle 的区别在于:oracle 拥有强大的计算能力,所以在 mysql 里面不建议使用。oracle 相对来说,在功能方面,比 mysql 要支持得更为全面一点

15.mysql sending data 占用时间较长,该怎么排查?

A:一般来说,sending data 占用时间长,通常来说,是扫描了过量的数据。对于这种情况,直接去分析这个 sql 语句的执行计划,是否走了索引,或者有其他的情况,导致它扫描了大量数据,或者说(sql 语句)里面存在子查询的情况

16.mysql count(*)  数据上千万时候非常慢,又要经常做统计,可以怎么做

A:一般这种场景,主要就是在分页的情况下,我理解,大部分的情况下就是做分页,每次要去做 count,又做 limit 。在数据量表大的情况下,limit 比较好优化,count(*) 比较容易,达到性能的上限。像这种情况,第一个要保证 count(*) 走的是索引,通过索引去扫描 count,做好了这点,count(*) 依然很慢的话,考虑在业务上做一些事,比如适当的妥协,不是感觉用户每一次去查看 count(*) 的时候,都必须要是准确的,用一定的缓存机制,选用服务器缓存也好,redis 缓存也好,采用过几分钟更新一次的方式,这样(的结果)就是再去获取 count 的数据的时候,不用等待太长的时间,当然有一个前提就是,对 count(*) 的查询,要求没有那么苛刻。

17.mysql 使用 group by ... order by ... limit [n] 有时候会选择错误的索引,对于这种情况该如何优化?除了使用 force index?

A:对于 Group by Order by 会选择错误索引的情况,首先要明确,在 mysql 里面,选择错误索引的原因,sql 语句里面有 group by,也有 order by,通常 mysql 会更加在意 where 条件,首先分析 sql 语句的构成,然后在根据表当中数据的分布规律,到底怎么样走索引更适合,最后再根据 sql 语句怎么,去判断建立怎样的索引是更加合适的。这里有一点建议,关于 sql 语句,这里可以利用 optimizer_trace 去分析,去看它为什么选择了,和咱们预期不一样的索引

18.数据量比较大的时候分页查询应该如何实现?

A:首先对于分页查询的这种优化的方式,在 mysql 数据库里面可以做的优化策略,就是在 PPT 里面讲到的覆盖索引的方式,就是先通过覆盖索引,去查找到主键id,再通过主键 id 的方式,去查找到这个表当中的数据。可能会存在这种情况,就是当数据量特别大的时候,通过覆盖索引去查询,还是会比较慢,这种情况的话,可以考虑在架构方面做一些扩展,在 mysql 里面没有太好的方式。第一,可以考虑用其他其他数据库产品代替,第二,可以在架构方面做扩展,然后看在业务上,能不能做一些妥协,比如禁止跳页,只让他点下一页,这样的话,每次点下一页,都会有一个 id,查询的 sql 语句就会类似 id > ? limit ?,那么不管我们的表,数据量有多大,查询的开销都不会很大。总的来讲,在数据量特别大的场景下,我们做很多事情都是很困难的,不可能通过标准的方式去看

19.查询时以时间顺序排序,在时间字段上建索引有帮助吗?还有其他方案吗?

A:给时间字段建索引排序的话,肯定是有帮助的,(给时间字段建索引)不管说是 between...and,range,还是 order by 也好,肯定是会有帮助的。关于其他方案,对于时间的查询,可能会有各种各样的需求,首先看时间存储的什么东西,比如年月日、时分秒,但是去做查询,是按照天或者其他什么做排序,可能需要表的结构上做改变,而不是通过索引/函数,去处理时间这个字段的值

20.一张10亿级别的大表,如何提升 count 的效率

A:对于10亿级别的大表,不建议在单一的 mysql 实例里面出一张10亿级别的大表。这个可以比较准确的说,如果在单一的 mysql 实例里面,有一张10亿级别的大表,不管我们怎样去查询,count(*) 效率都是很低的,除非有特别严谨的 where 条件,对于全表的 count(*) 查询,肯定还是很慢的。对于这种情况,可以用一些数仓的产品,或者用分库分表的策略,通过 MPP 的架构形式,来提升 count(*) 的效率

21.对索引顺序有建议吗 ?

A:建议排在前面的字段,一般是过滤性比较好的。对索引的顺序,也要看实际的业务场景,比如说排序的顺序,索引的顺序也要和排序的顺序一致,没有排序的场景,通常排在前面的字段,会选择过过滤型比较好的字段,因为对于复合索引来说,最前面的几个字段,也可以起到单列索引的效果






相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8天前
|
SQL 存储 关系型数据库
不允许你不知道的 MySQL 优化实战(三)
不允许你不知道的 MySQL 优化实战(三)
13 1
|
12天前
|
关系型数据库 MySQL
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-01
【4月更文挑战第18天】MySQL的InnoDB引擎支持行锁,而MyISAM只支持表锁。行锁在事务开始时添加,事务结束时释放,遵循两阶段锁协议。为减少锁冲突影响并发,应将可能导致最大冲突的锁操作放在事务最后。例如,在电影票交易中,应将更新影院账户余额的操作安排在事务末尾,以缩短锁住关键行的时间,提高系统并发性能。
14 4
|
12天前
|
关系型数据库 MySQL 数据库
【MySQL实战笔记】 06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?-01
【4月更文挑战第17天】MySQL的锁分为全局锁、表级锁和行锁。全局锁用于全库备份,可能导致业务暂停或主从延迟。不加锁备份会导致逻辑不一致。推荐使用`FTWRL`而非`readonly=true`因后者可能影响其他逻辑且异常处理不同。表级锁如`lock tables`限制读写并限定操作对象,常用于并发控制。元数据锁(MDL)在访问表时自动加锁,确保读写正确性。
64 31
|
8天前
|
SQL 关系型数据库 MySQL
不允许你不知道的 MySQL 优化实战(二)
不允许你不知道的 MySQL 优化实战(二)
16 2
|
3天前
|
缓存 关系型数据库 MySQL
MySQL数据库性能优化实战
【4月更文挑战第30天】本文探讨了MySQL性能优化实战技巧,包括硬件与配置优化(如使用SSD、增加内存和调整配置参数)、索引优化(创建合适索引、使用复合索引及定期维护)、查询优化(避免全表扫描、减少JOIN和使用LIMIT)、分区与分片(表分区和数据库分片),以及使用缓存、定期清理数据库和监控诊断。通过这些方法,可以提升数据库性能和响应速度。
|
5天前
|
存储 关系型数据库 MySQL
MySQL数据库实战:从入门到精通
本文介绍了MySQL的使用和优化,适合Web开发者阅读。首先,确保安装并配置好MySQL,熟悉SQL基础。接着,通过命令行客户端连接数据库,执行创建、查询、添加、修改和删除数据等操作。学习数据类型并创建表存储数据。最后,探讨了数据库优化,包括查询优化和索引使用,以提升性能。
14 2
|
7天前
|
安全 关系型数据库 MySQL
node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)
node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)
17 3
|
8天前
|
SQL 关系型数据库 MySQL
不允许你不知道的 MySQL 优化实战(一)
不允许你不知道的 MySQL 优化实战(一)
14 2
|
10天前
|
关系型数据库 MySQL 中间件
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测
【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。
22 1
|
13天前
|
SQL 关系型数据库 MySQL
Python与MySQL数据库交互:面试实战
【4月更文挑战第16天】本文介绍了Python与MySQL交互的面试重点,包括使用`mysql-connector-python`或`pymysql`连接数据库、执行SQL查询、异常处理、防止SQL注入、事务管理和ORM框架。易错点包括忘记关闭连接、忽视异常处理、硬编码SQL、忽略事务及过度依赖低效查询。通过理解这些问题和提供策略,可提升面试表现。
30 6

相关产品

  • 云数据库 RDS MySQL 版