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语句的优化相关推荐

  1. 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 ...

  2. 【Mysql】SQL性能分析

    [Mysql]SQL性能分析 文章目录 [Mysql]SQL性能分析 1. SQL执行频率 2. 慢查询日志 3. profile详情 4. explain 1. SQL执行频率 在控制台中通过命令 ...

  3. 如何写出高性能的SQL语句,及如何进行SQL性能分析与调优

    1.尽量使用索引 索引是数据库中重要的存储结构,对于查询耗时影响甚大,应避免导致索引无效的sql语句 索引失效的场景: 1.缺失索引 2.where 条件中的or 3.where条件表字段使用函数 4 ...

  4. 索引-性能分析-查看SQL执行频次以及慢查询日志

    索引语法 1.创建索引时候 [UNIQUE | FULLTEXT] 关键字是可选的: 1)加上 UNIUQE 就是创建唯一索引(唯一索引,说明改字段不能出现重复数据): 2)加上FULLTEXT 创建 ...

  5. 【MYSQL高级】Mysql的SQL性能分析【借助EXPLAIN分析】

    文章目录 性能分析 Mysql查询优化器(Mysql Query Optimizer) Mysql常见瓶颈 EXPLAIN简介 EXPLAIN是什么? EXPLAIN怎么使用? EXPLAIN能干嘛? ...

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

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

  7. SQL性能第1篇:关系优化

    女主宣言 本文旨在让大家了解关系优化的相关内容,包括它的需求和需要考虑的重要问题.在下一部分中,我们将研究查询分析和优化器可以部署的一些方法,以制定SQL访问路径.希望对大家在SQL性能优化方面有所帮 ...

  8. SQL性能分析工具SOAR介绍及实践

    1.什么是soar? SOAR(SQL Optimizer And Rewriter) 是一个对 SQL 进行优化和改写的自动化工具. 由小米人工智能与云平台的数据库团队开发与维护. 2.它有哪些功能 ...

  9. 【MySQL数据库 | 第十九篇】SQL性能分析工具

    目录 前言: SQL执行频率: 慢查询日志: profile: profile各个指令: 总结: 前言: 本篇我们将为大家讲解SQL性能的分析工具,而只有熟练的掌握了性能分析的工具,才可以更好的对SQ ...

最新文章

  1. 机器学习PAL数据预处理
  2. 代码农民从做事情的经验
  3. spyder ipython控制台_Spyder Ipython控制台完全忽略打印语句
  4. Python面向对象-特殊成员
  5. 解决远程登陆Linux误按ctrl+s锁屏
  6. E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
  7. 自定义头文件 No such file or directory
  8. 跟着李开复去硅谷,你有疑惑我帮问 | 互动一则
  9. 译: 6. 任务调度(定时执行任务)
  10. 猪是这样养成的(网络架构知识普及)
  11. 是的,我开通了小密圈
  12. linux shell将字符串分割数组
  13. 数据同步工具:Canal
  14. [80386]80x86汇编指令
  15. Java基本语法-Scanner类的应用_计算两个整数和
  16. python程序设计语言中的小于等于号_Python(matplotlib)小于或等于tex中的符号
  17. Java SE Lesson22_ClassLoader
  18. 1.3_VMare 16 虚拟机安装配置 CentOS-7-x86_64-DVD-2009+GUI+原生 Java 1.8+ibus+VMware Tools
  19. 汉诺塔问题模拟实现代码
  20. Android开发项目--跑腿APP-跑儿

热门文章

  1. 2000+停车场高精度地图数据,这家图商拿下首个合资品牌量产
  2. Flink 在顺丰的应用实践
  3. 我的软件--通讯录之三
  4. soul网关源码解析-环境搭建
  5. bcb mdi窗体画背景图片_vc++如何给窗体添加背景图片?
  6. 核磁共振测试常见的问题解答
  7. C++ STL之map映照容器
  8. 用unity shaderlab 实现「影之诗」中的闪卡特效(一)
  9. mysql 建表建索引
  10. 不使用第3个变量,实现两个数的对调