一、连接-配置优化

1.1 连接数过多问题

有时会碰到Mysql:error 1040:Too many connection的错误。原因:超过了服务端设置的最大并发连接数。

1.2 从两个方面解决问题

  • 服务端,增加服务端可用连接数;
  • 客户端,用连接池,设置合适的连接数;

1.2.1 服务端

1.增加服务端的连接数,修改max_connections的大小:

shouw variables like 'max_connections'; -- 修改最大连接数,当有多个应用连接的时候

2.或者,及时释放不活动的连接。交互式和非交互式的客户端的默认超时时间都是28800秒,8小时,我们可用把这个值调小。

show global variables like 'wait_timeout'; -- 及时释放不活动的连接,注意不要释放连接池还在使用的连接

1.2.2 客户端

从客户端来说,可以减少从服务端获取的连接,用连接池最合适。连接池的连接数量不一定越大越好。有时候连接池越大,效率反而越低。

Druid的默认最大连接池大小是8。Hikari的默认最大连接池大小是10。

Hikari文档给的连接池大小公式:机器核数*2+1,举例:4核机器,维护9个连接。

二、慢查询日志-slow query log

2.1 打开慢日志开关

因为开启慢查询日志是有代价的(更binlog、optimizer-trace一样),索引它默认是关闭的:

show variables like 'slow_query%';

慢查询参数:

show variables like '%QUERY%';

参数修改两种方式:

1.set动态修改参数(重启后失效);

--1开启,0关闭,重启后失效
set @@global.slow_query_log=l;
--默认10秒,另开一个窗口后才会查到最新值
set @@global.long_query_time=3;
show variables like '%long_query%';
Show variables like 'slow_query%';

2.修改配置文件my.cnf;

以下配置定义了慢查询日志的开关、慢查询的时间、日志文件的存放路径。

slow_query_log = ON
long_query_time= 2
slow_query_log_file =/var/lib/mysql/localhost-slow.log

2.2 慢sql日志分析

2.2.1 日志内容

less /var/lib/mysql/localhost-slow.log

有了慢查询日志,怎么去分析统计呢?比如哪条sql语句出现的慢查询次数最多,平均每次执行了多久?​​​​

2.2.3 mysqldumpslow

MySQL提供了 mysqldumpslow 的工具,在 MySQL 的 bin 目录下:

mysqldumpslow —help

例如:查询用时最多的10条慢SQL:

mysqldumpslow ・s t ・t 10 -g 'select' /var/lib/mysql/localhost-slow.log

  • Count代表这个SQL执行了多少次;
  • Time代表执行的时间,括号里面是累计时间;
  • Lock表示锁定的时间,括号里是累计;
  • Rows表示返回的记录数,括号是累计。

当然,有的时候查询慢,不一定是SQL语句的问题,也有可能是服务器状态的问题。索引我们也要掌握一些查看服务器和存储引擎状态的命令。

三、show processlist

  1. show full processlist:这是很重要的一个命令,用于显示用户运行线程。可以根据 id 号 kill 线程。
  2. showprocesslist:效果与show full processlist等同,只能列出当前100条;
  3. show status服务器运行状态;
  4. show engine存储引擎运行信息;

3.1 show processlist效果

各个列的含义:

①.id列,用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看
②.user列,显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句
③.host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户
④.db列,显示这个进程目前连接的是哪个数据库
⑤.command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等
⑥.time列,显示这个状态持续的时间,单位是秒
⑦.state列,显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成
⑧.info列,显示这个sql语句,是判断问题语句的一个重要依据

3.2 本人解决问题实践

3.2.1 报错

启动报错:has already more than 'max_user_connections' active connections

3.2.2 方法一:

  1. show PROCESSLIST;
  2. kill id;

 

3.2.3 方式二:

mysql实例的连接数max_user_connections 和max_connections 配置的那些事_51CTO博客_mysql max_connections 设置多少合适

四、Explain

explain 的结果有很多的字段,我们详细地分析一下。

4.1 id

id 是查询序列编号,每张表都是单独访问的,一个 SELECT 就会有一个序号。

  • id 值不同的时候,先査询 id 值大的(先大后小)
  • id 值相同时,表的查询顺序是从上往下顺序执行的。(根据 explan 出来的结果)
  • 如果 id 有相同也有不同, 就是 id 不同的先大后小,id 相同从上往下

连表查询,尽量查询中间结果小的表放前面;因为中间结果表会存在临时表,结果小,占有资源少;
——中心思想,小表驱动大表;小指的不是表数据量的大小,而是指过滤后的结果;

4.2 select type 查询类型

下面列举一些常见的查询类型:

  • SIMPLE:简单查询,不包含子查询,不包含关联查询 union
  • PRIMARY:子查询 SQL 语句中的主查询,也就是最外面那层查询
  • SUBQUERY:子查询中所有的内层查询都是 SUBQUERY 类型
  • DERIVED:衍生查询,表示在得到最终查询结果之前会用到临时表
  • UNION:用到了 UNION 查询
  • UNION RESULT:主要是显示哪些表之间存在 UNION 查询。比如 <union2,3>代表 id = 2 和 id = 3 的查询存在 UNION

4.2.1 实例

4.3 type连接类型

在常见的连接类型中:system > const > eq_ref > ref > range > index > all

这里并没有列举全部(其他:fulltext、ref_or_null、index_merger、unique_subquery、index_subquery)。

以上的类型除了 all ,都能用到索引。

  • const:主键索引或者唯一索引,只能查到一条数据的 SQL
  • system:system 是 const 的一种特例,只有一行满足条件,对于 MyISAM、 Memory 的表,只能查询到一条记录,就是 system
  • eq_ref:通常出现在多表的 join 查询,被驱动表通过唯一索引 (UNIQUE 或者 PRIMARY KEY)进行访问,此时被驱动表的访问方式就是 eq_ref
  • ref:查询用到了非唯一性索引,或者关联操作值使用了索引的最左前缀
  • range:索引范围扫描。如果 where 后面是 between and 或 < 或 > 或 >= 或 <= 或 in 这些,type 类型就位 range
  • index:Full Index Scan,查询全部索引中的数据(比不走索引要快)
  • all:Full Table Scan,如果没有索引或者没用用到索引,type 就是 ALL
  • NULL:不用访问表或者索引就能得到结果。例如:EXPLAN select 1 from dual where 1 = 1;

小结1:system、const、eq_ref,都是可遇不可求的,基本很难优化到这个状态。

小结2:一般来说,需要保证查询的 type 至少打到 range 级别,最好能达到 ref。

小结3:ALL (全表扫描)和 index(查询全部索引)都是需要优化的。

4.3.1 图示

从上往下,性能越来越差;

4.4 possible_key 、key

可能用到的索引和实际用到的索引,如果是 NULL 就代表没有用到索引。

possible_key 可以有多个,可能用到索引不代表一定用到索引。

possible_key 为空,key也可能有值(覆盖索引的情况)。

4.4.1 实例

如果possible_keys是null,key有没有可能不为null?

——答,有,覆盖索引,索引下推;

4.5 key_len

索引的长度(使用的字节数),跟索引字段的类型和长度有关。

4.5.1 长度解析

索引长度:1023是怎么来的?

答:

  • name长度是255,编码是utf8mb4,一个字符占4个字节:255*4=1020;

还有3个:

  • name字段是变长的,需要额外两个字节存储变长的长度;+2
  • 可以为null,还需要一个额外字节存储;+1

4.6 rows

MySQL 认为扫描多少行才能返回请求的数据,是一个预估值。一般来说行数越少越好。

简单来说,就说预估需要扫描多少数据。

4.7 filtered

这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,它是一个百分比。

如果比例很低,说明存储引擎层返回的数据需要经过大量过滤,这个是会消耗性能的,需要关注。

4.8 ref

使用哪个列或者常数和索引一起从表中筛选数据。

简而言之:表示过滤数据的时候,用的是常量还是什么字段?

4.9 Extra

执行计划给出的额外的信息说明:

  • using index:用到了覆盖索引,不需要回表
  • using where:使用了where过滤,表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤(跟是否使用索引没有关系)
  • Using index condition(索引条件下推):存储引擎帮忙过滤数据,正常是在 Server 层过滤
  • using filesort:不能使用索引来排序,用到了额外的排序(跟磁盘或文件没有关系)。需要优化。
  • using temporary:用到了临时表。
    例如:
    1、distinct 非索引列
    2、group by 非索引列
    3、使用 join 的时候,group任意列

4.9.1 图示

五、SQL与索引优化

5.1 mysql explain format = json 查看sql执行效率

如果要分析语句时,拿到一个更详细的值,可以用 Explain format=json ;

5.2 关于limit类语句优化

当我们的 SQL 语句比较复杂,有多个关联和子查询的时候,就要分析 SQL 语句有没有改写的方法。

5.3 一个sum语句性能提升3倍的优化案例

https://gper.club/articles/7e7e7f7ff4g5egc2g63

5.3.1 案例总结:

优化前:

SELECTcount( IF ( b.busi_status = '1', b.busi_status, NULL ) ) AS totalPaySuccessCount,sum( IF ( b.busi_status = '1', b.sal_real_pay, 0 ) ) AS totalPaySuccessAmount,count( IF ( b.busi_status = '2', b.busi_status, NULL ) ) AS totalPayErrorCount,sum( IF ( b.busi_status = '2', b.sal_real_pay, 0 ) ) AS totalPayErrorAmount
FROMsal_orders AS aLEFT JOIN sal_orders_detail b ON a.busi_proc_id = b.order_id
WHEREa.enable_status =1AND a.corp_no = '2'

优化后:

SELECTsum( b.sal_real_pay ) AS totalPaySuccessAmount
FROMsal_orders AS aLEFT JOIN sal_orders_detail b ON a.busi_proc_id = b.order_id
WHEREa.enable_status =1AND a.corp_no = '2'and b.busi_status = '2'unionSELECTsum( b.sal_real_pay ) AS totalPayErrorAmount
FROMsal_orders AS aLEFT JOIN sal_orders_detail b ON a.busi_proc_id = b.order_id
WHEREa.enable_status =1AND a.corp_no = '2'and b.busi_status = '1'

sum() 函数里不要加if,会带来额外开销。把if条件放在where后,改为union + where实现功能;

六、存储引擎

6.1 存储引擎的选择

为不同的业务表选择不同的存储引擎,例如:

  • 查询插入操作多的业务表,用MylSAM
  • 临时数据用Memeroy
  • 常规的并发大更新多的表用InnoDB

6.2 分表或者分区

订单历史表:在年底为下一年度建立12个分区,每个月一个分区。

渠道交易表:分成:当日表、当月表、历史表,历史表再做分区。

6.3 字段的定义

原则:使用可以正确存储数据的最小数据类型。

为每一列选择合适的字段类型:

6.3.1 整数类型

INT有6种类型,不同的类型的最大存储范围是不一样的,占用的存储空间也是不一样的。

举例:存储性别字段,用 TINYINT

6.3.2 字符类型

变长情况下,varchar 更节省空间,但是对于 varchar 字段,需要一个字节来记录长 度。比如:联系地址。

固定长度的用 char ,不要用 varcharo 比如:行政区划编码。

6.3.3 非空

非空字段尽量定义成 NOT NULL,提供默认值,或者使用特殊值、空串代替 nullo NULL 类型的存储、优化、使用都会存在问题。

6.3.4 不要用外键、触发器、视图

降低了可读性;影响数据库性能,应该把把计算的事情交给程序,数据库专心做存储;数据的完整性应该在程序中检查。

6.3.5 大文件存储

图片和音频、视频怎么存储?

不要用数据库存储图片(比如base64编码)或者大文件。

把文件放在 NAS上,数据库只需要存储URI (相对路径),在应用中配置 NAS 服 务器地址。

6.3.6 表拆分或者字段冗余

表拆分:将不常用的字段拆分出去,避免列数过多和数据量过大

字段冗余:合同表的客户姓名

七、优化体系总结

7.1 你会从哪些维度优化数据库?你会怎么回答呢?

  • SQL与索引
  • 存储引擎与表结构
  • 数据库架构
  • MySQL 配置
  • 硬件与操作系统
  • 除了对于代码、SQL语句、表定义、架构、配置优化之外,业务层面的优化也不能忽视,比如限流,或者引入 MQ 削峰等等

7.2 业务层面

除了对于代码、 SQL 语句、表定义、架构、配置优化之外,业务层面的优化也不能忽视。

举两个例子:

  1. 在某一年的双十一,为什么会做一个充值到余额宝和余额有奖金的活动?现在会推荐大家用花哩支付,而不是银行卡支付?因为使用余额或者余额宝付款是记录本地或者内部数据库,而使用银行卡付款,需要调用接口,操作内部数据库肯定更快。
  2. 在某一年的双十一,为什么在凌晨禁止查询今天之外的账单?为什么小鸡的饲料发放延迟了?这是一种降级措施,用来保证当前最核心的业务。
  3. 某银行的交易记录,只能按月份查询。
  4. 最近几年的双十一,为什么 11 月 1 日就开始了?变成了各种定金红包模式?—— 预售分流。

7.3 应用层面

在应用层面同样有很多其他的方案来优化,达到尽量减轻数据库的压力的目的,比如限流,或者引入 MQ 削峰,等等等等。

为什么同样用 M ySQL ,有的公司可以抗住百万千万级别的并发,而有的公司几百个并发都扛不住,关键在于怎么用。所以,用数据库慢,不代表数据库本身慢,有的时候还要往上层去优化。

当然,如果关系型数据库解决不了的问题,我们可能需要用到搜索引擎或者大数据的方案了,并不是所有的数据都要放到关系型数据库存储。

八、 优化案例,一些优化建议

8.1 服务端状态分析:

如果出现连接变慢,查询被阻塞,无法获取连接的情况。

  1. 重启!
  2. show processlist 查看线程状态,连接数数量、连接时间、状态;
  3. 查看锁的状态;
  4. kill 有问题的线程;

8.2 对于具体的慢SQL:

8.2.1 分析查询基本情况

涉及到的表的表结构,字段的索引情况、每张表的数据量、查询的业务含义。这个非常重要,因为有的时候你会发现 SQL 根本没必要这么写,或者表设计是有问 题的。

8.2.2 找出慢的原因

  1. 查看执行计划,分析SQL的执行情况,了解表访问顺序、访问类型、索引、扫描行数等信息。
  2. 如果总体的时间很长,不确定哪一个因素影响最大,通过条件的增减,顺序的调整,找出引起查询慢的主要原因,不断地尝试验证。

找到原因:比如是没有走索引引起的,还是关联查询引起的,还是 order by 引起的。

找到原因之后:

8.2.3 对症下药

1、 创建索引或者联合索引

2、 改写SQL,这里需要平时积累经验,例如:

​ 1) 使用小表驱动大表

​ 2) 用 join 来代替子查询

​ 3) not exist 转换为 left join IS NULL

​ 4) or 改成 union

​ 5) 如果结果集允许重复的话,使用 UNION ALL 代替 UNION

​ 6) 大偏移的 limit ,先过滤再排序。

如果SQL本身解决不了了,就要上升到表结构和架构了。

不确定哪一个因素影响最大,通过条件的增减,顺序的调 整,找出引起查询慢的主要原因,不断地尝试验证。

找到原因:比如是没有走索引引起的,还是关联查询引起的,还是 order by 引起的。

3.表结构(冗余、拆分、not null等)、架构优化(缓存读写分离分库分表)。

4.业务层优化,必须条件是否必要。

掌握正确的调优思路,才是解决数据库性能问题的根本。

优化器-SQL语句分析与优化相关推荐

  1. Sql性能优化之sql语句的写法

    Sql性能优化之sql语句的写法 一.引言 系统优化中一个很重要的方面就是SQL语句的优化.对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其 ...

  2. THOR:MindSpore 自研高阶优化器源码分析和实践应用

    摘要:这篇文章跟大家分享下THOR的实践应用.THOR算法的部分内容当前已经在MindSpore中开源 本文分享自华为云社区<MindSpore 自研高阶优化器源码分析和实践应用>,原文作 ...

  3. 3mysql优化之SQL语句调优

    文件在:E:\学习文档子目录压缩\数据库\mysql\mysql优化\蚂蚁\蚂蚁1\3mysql优化之SQL语句调优 或 我的网盘\我的笔记\学习文档子目录压缩\数据库\mysql\mysql优化\蚂 ...

  4. MySQ5.7数据库-基准测试SQL语句分析

    文章目录 MySQL基准测试 什么是基准测试 基准测试特点 压力测试特点 基准测试的目的 如何进行基准测试 对整个系统进行基准测试 MySQL基准测试的常见指标 MySQL基准测试之mysqlslap ...

  5. sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取

    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取 原文:sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取 在多人开发中最头疼的是人少事多没有时间进行codereview ...

  6. 【单目标优化求解】基于matlab增强型黑猩猩优化器算法求解单目标优化问题【含Matlab源码 2013期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[单目标优化求解]基于matlab增强型黑猩猩优化器算法求解单目标优化问题[含Matlab源码 2013期] 点击上面蓝色字体,直接付费下 ...

  7. 一条有意思的SQL语句分析

    一条有意思的SQL语句分析        这条语句,说实在的困扰了我很久了,以前由于工作忙及工作中很少用到此种写法,即使有碰到这种要求也用别的语句代替或用另外一种方案实现,所以一直没空理它.这次星期天 ...

  8. 爆肝,52条SQL语句,性能优化,干货必收藏 !

    作者 | SimpleWu 来源 | cnblogs.com/SimpleWu/p/9929043.html SQL语句性能优化 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...

  9. mysql解释器优化_MySQL——SQL性能分析优化利器之Explain

    系统性能的优劣取决于我们sql的查询速度,MySQL Explain命令是分析SQL性能及优化不可缺少的一部分. Explain被我们称为解释器,通过 explain 我们可以知道以下信息:表的读取顺 ...

最新文章

  1. 多线程批量拆分List导入数据库
  2. Git@OSC 增加 SVN 支持
  3. html javascript 引号
  4. Android:禁用listView上的突出显示单击
  5. 北京协和医学院823计算机原理,2017年北京协和医学院放射医学研究所(天津)823计算机原理考研题库...
  6. 同一个网站下不同应用程序可以不同Framework版本
  7. 盘点大数据的十大发展方向,Scale-out将成主流
  8. 12月12日习题答案大剖析!再接再厉
  9. 苹果手机怎么编辑word文档_可以一键导入word图文的微信编辑软件有什么?编辑器怎么使用?...
  10. 计算机网络前三章试题,计算机网络前三章复习试题PPT课件.ppt
  11. 商业模式画布模板——From 《商业模式新生代》
  12. PanDownload复活了!60MB/s!
  13. 概率论和数理统计知识点总结
  14. 【知识必备】RxJava+Retrofit二次封装最佳结合体验,打造懒人封装框架~
  15. 电脑USB口输出的是什么电平
  16. 幽门杆菌来源_肉毒杆菌毒素和设计移情的艺术
  17. 盘古开源资讯:夯实产业基础,打造汽车电子芯片产业高地
  18. 服务器使用上突然卡了,导致服务器卡顿的原因有哪些,该怎么处理?
  19. 如何使用开源合成器Natron入门
  20. 冲鸭!羊毛薅起来!当当618专享不到4折,Python书籍囤起来!

热门文章

  1. python opencv 读取图片_Python opencv 读取图像
  2. 图论——最短路径之渡河问题
  3. 两耳不闻窗外事 一心只读圣贤书
  4. win7(32bit)下完整的搭建apache(2.2.x)+openssl(0.9.6-1.0.1升级)过程
  5. Linux入门推荐书籍
  6. git core.autocrlf配置说明
  7. 步进电机调速,S曲线调速算法你会吗?
  8. 语雀 | markdown文档编写常用快捷键
  9. pthread_cond_wait和pthread_cond_signal
  10. python图像倾斜校正_python 图像倾斜校正