当前位置: 首页 > news >正文

MySQL之SQL优化

目录

1.插入数据

2.大批量插入数据

3.order by优化

4.group by优化

5.limit优化

6.count优化

count用法

7.update优化


1.插入数据

如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化

第一个:批量插入数据

Insert  into  tb_test  values (1, 'Tom '), (2, 'Cat '), (3, 'Jerry ');

第二个:手动控制事务

start  transaction;
insert  into  tb_test  values (1, 'Tom '), (2, 'Cat '), (3, 'Jerry ');
insert  into  tb_test  values (4, 'Tom '), (5, 'Cat '), (6, 'Jerry ');
insert  into  tb_test  values (7, 'Tom '), (8, 'Cat '), (9, 'Jerry ');
commit;

第三个:主键顺序插入,性能要高于乱序插入

主键乱序插入 : 8  1  9  21  88  2  4  15  89  5  7  3
主键顺序插入 : 1  2  3  4  5  7  8  9  15  21  88  89

2.大批量插入数据

如果一次性需要插入大批量数据(比如 : 几百万的记录 ),使用insert语句插入性能较低, 此时可以使 用MySQL数据库提供的load指令进行插入。操作如下:

-- 执行load指令将准备好的数据,加载到表结构中
load  data  local  infile  '/root/sql1.log '  into  table  tb_user  fields
terminated  by  ', '  lines  terminated  by  '\n ' ;
 

3.order by优化

MySQL的排序,有两种方式:

  • Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。

  • Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要 额外排序,操作效率高。 对于以上的两种排序方式, Using index的性能高,而Using filesort的性能低,我们在优化排序 操作时,尽量要优化为 Using index。

由于 name, price都没有索引,所以此时再排序时,出现Using filesort, 排序性能较低。

explain select id,name,price from tb_sku order by name,price;

创建索引

create index sku_name_price on tb_sku(name,price);

建立索引之后,再次进行排序查询,就由原来的Using filesort, 变为了 Using index,性能就是比较高的了。

explain select id,name,price from tb_sku order by name,price;

4.group by优化

在没有索引的情况下,执行如下SQL,查询出现Using temporary这种效率低

explain select profession,count(*) from tb_user group by profession;

我们再针对于 profession , age, status 创建一个联合索引

create index idx_user_pro_age_sta on tb_user (profession,age,status);

再执行前面相同的SQL查询出现Using index这种效率高

explain select profession,count(*) from tb_user group by profession;

如果仅仅根据age分组,就会出现 Using temporary ; 在联合索引中,也是符合最左前缀法则的。

explain select age,count(*) from tb_user group by age;

5.limit优化

在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。

我们一起来看看执行limit分页查询耗时对比:

select * from tb_sku limit 10000,10;
select * from tb_sku limit 100000,10;
select * from tb_sku limit 1000000,10;
select * from tb_sku limit 2000000,10;

通过测试我们会看到,越往后,分页查询效率越低,这就是分页查询的问题所在。

优化思路 : 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查 询形式进行优化。

explain   select  *  from  tb_sku  t  ,  (select  id  from  tb_sku  order  by  id
limit  2000000,10)  a  where t.id  =  a.id;

优化前:

优化后:

6.count优化

数据量很大,在执行count操作时,相对是耗时的。

查询200万的数据时:

select  count (*)  from  tb_user ;

如果说要大幅度提升InnoDB表的count效率,主要的优化思路:自己计数(可以借助于redis这样的数 据库进行 ,但是如果是带条件的count又比较麻烦了)

count用法

count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1, 否则不加,最后返回累计值。

用法: count (*)、 count (主键)、 count (字段)、 count (数字)

count用 法含义
count(主 键)InnoDB 引擎会遍历整张表,把每一行的 主键id 值都取出来,返回给服务层。 服务层拿到主键后,直接按行进行累加(主键不可能为null)
count(字 段)没有not null 约束 : InnoDB 引擎会遍历整张表把每一行的字段值都取出 来,返回给服务层,服务层判断是否为null,不为null,计数累加。 有not null 约束: InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返 回给服务层,直接按行进行累加。
count(数 字)InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1” 进去,直接按行进行累加。
count(*)InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

按照效率排序的话, count(字段) < 量使用 count()。 count(主键 id) < count(1) ≈ count(),所以尽量使用 count(*)。

7.update优化

我们主要需要注意一下update语句执行时的注意事项。

update tb_user set name = 'javaEE' where id  = 1;

当我们在执行删除的SQL语句时,会锁定id为1这一行的数据,然后事务提交之后,行锁释放。

但是当我们在执行如下SQL时。

update tb_user set name = '曹操' where name = '孙悟空' ;

当我们开启多个事务,在执行上述的SQL时,我们发现行锁升级为了表锁。 导致该update语句的性能大大降低。

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁升级为表锁 。

http://www.dtcms.com/a/138505.html

相关文章:

  • 在RAG大模型中token怎么作为有效的数据,体现大模型能力的
  • uniapp APP端 DOM生成图片保存到相册
  • Three.js + React 实战系列 : 从零搭建 3D 个人主页
  • RT-Thread学习笔记(一)
  • java 设计模式之单例模式
  • 关于 雷达(Radar) 的详细解析,涵盖其定义、工作原理、分类、关键技术、应用场景、挑战及未来趋势,结合实例帮助理解其核心概念
  • 【模型常见评价指标(分类)】
  • 从 ComponentActivity 看 Android Activity 的演变与 Jetpack 架构融合
  • 驱动开发硬核特训 · Day 14:深入理解 Power 管理驱动架构与实战应用
  • SQL Server 存储过程
  • webgl入门实例-08索引缓冲区的基本概念
  • 02、GPIO外设(一):基础知识
  • 3D人脸扫描技术如何让真人“进入“虚拟,虚拟数字人反向“激活“现实?
  • 机器学习在催化剂设计中的应用理论加实操
  • Muduo网络库实现 [十四] - HttpResponse模块
  • 【AI提示词】哲学三问
  • Java基础系列-LinkedList源码解析
  • 面试情景题:企业内部系统如何做微前端拆分,如何通信?
  • IDEA 中 Scala 项目远程连接虚拟机 Spark 环境
  • OpenCV 模板匹配方法详解
  • 中间件--ClickHouse-7--冷热数据分离,解决Mysql海量数据瓶颈
  • springboot自定义starter(避坑教学)
  • OpenCV day5
  • kubernetes-高频率使用命令
  • LeetCode 2176.统计数组中相等且可以被整除的数对:两层遍历模拟
  • 【专题刷题】双指针(三):两数之和,三数之和,四数之和
  • 第八章:探索新兴趋势:Agent 框架、产品与开源力量
  • 新能源汽车能量流测试的传感器融合技术应用指南
  • .net C# 使用Epplus库将Datatable导出到Excel合并首列
  • Python 让课堂“沉浸式进化”——虚拟现实教学辅助工具的开发实战