sql性能分析以及sql语句的优化
sql性能分析的几种方式
SQL执行频率
show [session|global] status like ‘com__(七个下划线)_’;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次
通过这个指令我们可以查看当前数据库是以查询为主还是更新为主。如果是以查询为主,那么就要考虑对数据库的索引进行优化了。
慢查询日志。定位需要对哪些查询语句进行优化。
MySQL的配置文件(/etc/my.cnf)中配置如下信息
# 开启MySQL慢日志查询开关 slow_query_log=1 # 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志 long_query_time=2
日志信息所在:/var/lib/mysql/localhost-slow.log
这样在慢查询日志中就会记录那些查询效率较低的sql语句
profile :这个可以让我们知道sql语句运行时的时间都消耗在哪里了,用的不是很多
explain:获取sql的执行计划
explain
使用方式:直接在sql语句前面加explain,或者加desc,作用基本一致,使用expalin多一些
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件 ;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-59U9tmMo-1664243430019)(/Users/wangkx/Desktop/wkx的md笔记/img/image-20220926195406219.png)]
各个字段的含义:
- id:select查询的序列号。表示查询中执行select子句或者是操作表的顺序,当id相同的时候,执行的顺序是从上往下,当id不同的时候,id值越大,执行顺序越靠前
- select_type:表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION 中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等
- type:表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、 index、all
- possible_key:显示在这张表上,此次查询可能会用到的索引。有一个或多个
- key :此次查询实际用到的索引,如果是null值的话就说明没有使用索引
- key_len:表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下, 长度越短越好
- rows:MySQL认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的
- filtered :表示返回结果的行数占需读取行数的百分比, filtered 的值越大越好
sql语句优化
插入数据优化
对于insert
批量插入:一般是500-1000条
手动提交事务:执行一系列insert之前开启事务,执行完提交事务,避免事务的频繁开启和提交
按照主键顺序插入
对于一次有几百万条数据
这个时候使用insert效率会很低,可以使用load指令把本地文件大批量加载到数据库中
-- 客户端连接服务端时,加上参数 -–local-infilemysql –-local-infile -u root -p
-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关set global local_infile = 1;
-- 执行load指令将准备好的数据,加载到表结构中load data local infile '/root/sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n' ; //每个字段按照逗号隔开,行间按照换行隔开
主键优化
- 尽量降低主键长度,因为二级索引会有很多,它的叶子结点存储的是主键值,主键长度过大会导致单个节点体积变大,占用过多磁盘空间
- 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
- 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。uuid是乱序的会导致页分裂,身份证号太长了
- 尽量避免对主键的修改
在InnoDB引擎中,数据行是记录在逻辑结构 page 页中的,每一个页的大小是固定的,默认16K,所以说一个页中所存储的行也是有限的。然后因为使用的是B+索引,表数据是按照主键顺序存储的,页与页之间的顺序是有序的。
页分裂
mysql规定每个页至少包含两个数据(只有一个数据就是链表了)。
当主键顺序插入时,第一个页满了就往第二个页写,页与页之间使用指针相连。
但是当主键乱序插入时,新数据不会直接插入到空白页(这样做数据会无序),而是会把对应页的后半部分数据移动到空白页,然后再把要插入的值插入到空白页。最后还得重新设置链表的指针。效率就很低了
页合并
删除数据时,把对应位置标记为无效,当页中删除的记录达到 一个阈值的时候(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
order by优化
首先MySQL的排序有两种方式
- Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sortbuffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序
- Using index : 通过扫描索引文件就可以直接返回有序数据,这种情况即为 using index,不需要额外排序,操作效率高
原则:
- 我们可以根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则
- 尽量使用覆盖索引,回表操作一定会Using filesort
- 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k),避免数据在磁盘中排序
group by优化
在分组操作时,给group by后的条件加索引,尽量加联合索引
分组操作时,索引的使用也是满足最左前缀法则的
limit优化
在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低,因为会先对前面的记录排序
优化思路: 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化
举例:我们可以先使用limit只查出id(用到覆盖索引),然后把这张结果表和原表做一次连表查询
select * from tb_sku t ,
(select id from tb_sku order by id limit 2000000,10) a
where t.id = a.id;
count优化
不是很容易优化,非要优化的话可以使用redis自己计数。
- count(字段):没有not null 约束 : InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。有not null 约束:InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。
- count(主键):InnoDB 引擎会遍历整张表,把每一行的 主键id 值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)
- count(数字):InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加
- count(*):InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。
按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(),所以尽量使用 count()。
update优化
在InnoDB引擎中,执行一条update语句:update course set name = ‘SpringBoot’ where name = ‘PHP’
如果我们给name字段加了索引,此时InnoDB加的是行锁,其他事务可以操作别的记录,并发性能高
但是如果name字段没有索引,或者name字段索引失效,update时直接升级为表锁,其他事务无法操作数据库表。
所以要尽量使用索引字段为条件来更新数据,增加并发性。
sql性能分析以及sql语句的优化相关推荐
- MySQL 进阶 索引 -- SQL性能分析(SQL执行频率:查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次、慢查询日志、 profile详情、explain)
文章目录 1. SQL性能分析 1.1 SQL执行频率(可以查看当前数据库SQL的访问频次) 1.2 慢查询日志(可以记录用时较长的SQL) 1.2.1 开启慢查询日志 1.2.2 慢查询日志测试 1 ...
- 【Mysql】SQL性能分析
[Mysql]SQL性能分析 文章目录 [Mysql]SQL性能分析 1. SQL执行频率 2. 慢查询日志 3. profile详情 4. explain 1. SQL执行频率 在控制台中通过命令 ...
- 如何写出高性能的SQL语句,及如何进行SQL性能分析与调优
1.尽量使用索引 索引是数据库中重要的存储结构,对于查询耗时影响甚大,应避免导致索引无效的sql语句 索引失效的场景: 1.缺失索引 2.where 条件中的or 3.where条件表字段使用函数 4 ...
- 索引-性能分析-查看SQL执行频次以及慢查询日志
索引语法 1.创建索引时候 [UNIQUE | FULLTEXT] 关键字是可选的: 1)加上 UNIUQE 就是创建唯一索引(唯一索引,说明改字段不能出现重复数据): 2)加上FULLTEXT 创建 ...
- 【MYSQL高级】Mysql的SQL性能分析【借助EXPLAIN分析】
文章目录 性能分析 Mysql查询优化器(Mysql Query Optimizer) Mysql常见瓶颈 EXPLAIN简介 EXPLAIN是什么? EXPLAIN怎么使用? EXPLAIN能干嘛? ...
- mysql解释器优化_MySQL——SQL性能分析优化利器之Explain
系统性能的优劣取决于我们sql的查询速度,MySQL Explain命令是分析SQL性能及优化不可缺少的一部分. Explain被我们称为解释器,通过 explain 我们可以知道以下信息:表的读取顺 ...
- SQL性能第1篇:关系优化
女主宣言 本文旨在让大家了解关系优化的相关内容,包括它的需求和需要考虑的重要问题.在下一部分中,我们将研究查询分析和优化器可以部署的一些方法,以制定SQL访问路径.希望对大家在SQL性能优化方面有所帮 ...
- SQL性能分析工具SOAR介绍及实践
1.什么是soar? SOAR(SQL Optimizer And Rewriter) 是一个对 SQL 进行优化和改写的自动化工具. 由小米人工智能与云平台的数据库团队开发与维护. 2.它有哪些功能 ...
- 【MySQL数据库 | 第十九篇】SQL性能分析工具
目录 前言: SQL执行频率: 慢查询日志: profile: profile各个指令: 总结: 前言: 本篇我们将为大家讲解SQL性能的分析工具,而只有熟练的掌握了性能分析的工具,才可以更好的对SQ ...
最新文章
- 机器学习PAL数据预处理
- 代码农民从做事情的经验
- spyder ipython控制台_Spyder Ipython控制台完全忽略打印语句
- Python面向对象-特殊成员
- 解决远程登陆Linux误按ctrl+s锁屏
- E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
- 自定义头文件 No such file or directory
- 跟着李开复去硅谷,你有疑惑我帮问 | 互动一则
- 译: 6. 任务调度(定时执行任务)
- 猪是这样养成的(网络架构知识普及)
- 是的,我开通了小密圈
- linux shell将字符串分割数组
- 数据同步工具:Canal
- [80386]80x86汇编指令
- Java基本语法-Scanner类的应用_计算两个整数和
- python程序设计语言中的小于等于号_Python(matplotlib)小于或等于tex中的符号
- Java SE Lesson22_ClassLoader
- 1.3_VMare 16 虚拟机安装配置 CentOS-7-x86_64-DVD-2009+GUI+原生 Java 1.8+ibus+VMware Tools
- 汉诺塔问题模拟实现代码
- Android开发项目--跑腿APP-跑儿