MySql---进阶篇(六)---SQL优化

news2025/1/6 8:37:05

6.1:insert的优化:

(1)普通的插入数据

如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化。
insert into tb_test values(1,'tom');
insert into tb_test values(2,'cat');
insert into tb_test values(3,'jerry');
1). 优化方案一
批量插入数据
Insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
2). 优化方案二
手动控制事务
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;
3). 优化方案三
主键顺序插入,性能要高于乱序插入。
主键乱序插入 : 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 指令进行插入。操作如下:

可以执行如下指令,将数据脚本文件中的数据加载到表结构中:
-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-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' ;
主键顺序插入性能高于乱序插入
示例演示 :
A. 创建表结构
CREATE TABLE `tb_user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`name` VARCHAR(20) NOT NULL,
`birthday` DATE DEFAULT NULL,
`sex` CHAR(1) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_user_username` (`username`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
B. 设置参数
-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-local-infile -u root -p
-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
C. load 加载数据
load data local infile '/root/load_user_100w_sort.sql' into table tb_user
fields terminated by ',' lines terminated by '\n' ;

我们看到,插入 100w 的记录, 17s 就完成了,性能很好。
load 时,主键顺序插入性能高于乱序插入。

6.2,主键优化:

在上一小节,我们提到,主键顺序插入的性能是要高于乱序插入的。 这一小节,就来介绍一下具体的原因,然后再分析一下主键又该如何设计。
1). 数据组织方式
InnoDB 存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表
(index organized table IOT)

行数据,都是存储在聚集索引的叶子节点上的。而我们之前也讲解过 InnoDB 的逻辑结构图:

InnoDB 引擎中,数据行是记录在逻辑结构 page 页中的,而每一个页的大小是固定的,默认 16K 。那也就意味着, 一个页中所存储的行也是有限的,如果插入的数据行row 在该页存储不小,将会存储到下一个页中,页与页之间会通过指针连接。
2). 页分裂
页可以为空,也可以填充一半,也可以填充 100% 。每个页包含了 2-N 行数据 ( 如果一行数据过大,会行溢出) ,根据主键排列。
A. 主键顺序插入效果
. 从磁盘中申请页, 主键顺序插入

. 第一个页没有满,继续往第一页插入

. 当第一个也写满之后,再写入第二个页,页与页之间会通过指针连接

. 当第二页写满了,再往第三页写入

B. 主键乱序插入效果
. 加入 1#,2# 页都已经写满了,存放了如图所示的数据

. 此时再插入 id 50 的记录,我们来看看会发生什么现象
会再次开启一个页,写入新的页中吗?
不会。因为,索引结构的叶子节点是有顺序的。按照顺序,应该存储在 47 之后。
但是 47 所在的 1# 页,已经写满了,存储不了 50 对应的数据了。 那么此时会开辟一个新的页 3#
但是并不会直接将 50 存入 3# 页,而是会将 1# 页后一半的数据,移动到 3# 页,然后在 3# 页,插入 50
移动数据,并插入 id 50 的数据之后,那么此时,这三个页之间的数据顺序是有问题的。 1# 的下一个页,应该是3# 3# 的下一个页是 2# 。 所以,此时,需要重新设置链表指针
上述的这种现象,称之为 " 页分裂 " ,是比较耗费性能的操作。
3). 页合并
目前表中已有数据的索引结构 ( 叶子节点 ) 如下
当我们对已有数据进行删除时,具体的效果如下 :
当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记( flaged )为删除并且它的空间变得允许被其他记录声明使用。
当我们继续删除 2# 的数据记录
当页中删除的记录达到 MERGE_THRESHOLD (默认为页的 50% ), InnoDB 会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
删除数据,并将页合并之后,再次插入新的数据 21 ,则直接插入 3#
这个里面所发生的合并页的这个现象,就称之为 " 页合并 "
知识小贴士:
MERGE_THRESHOLD :合并页的阈值,可以自己设置,在创建表或者创建索引时指定。
4). 索引设计原则
满足业务需求的情况下,尽量降低主键的长度。
插入数据时,尽量选择顺序插入,选择使用 AUTO_INCREMENT 自增主键。
尽量不要使用UUID 做主键或者是其他自然主键,如身份证号。
业务操作时,避免对主键的修改。

6.3,order by优化:

MySQL 的排序,有两种方式:
Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区 sort
buffer 中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。
Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index ,不需要
额外排序,操作效率高。
对于以上的两种排序方式, Using index 的性能高,而 Using filesort 的性能低,我们在优化排序
操作时,尽量要优化为 Using index
接下来,我们来做一个测试:
A. 数据准备
把之前测试时,为 tb_user 表所建立的部分索引直接删除掉
drop index idx_user_phone on tb_user;
drop index idx_user_phone_name on tb_user;
drop index idx_user_name on tb_user;

B. 执行排序 SQL
explain select id ,age,phone from tb_user order by age;

explain select id,age,phone from tb_user order by age, phone ;

由于 age, phone 都没有索引,所以此时再排序时,出现 Using filesort , 排序性能较低。
C. 创建索引
-- 创建索引
create index idx_user_age_phone_aa on tb_user(age,phone);
D. 创建索引后,根据 age, phone 进行升序排序
explain select id,age,phone from tb_user order by age;
建立索引之后,再次进行排序查询,就由原来的 Using filesort , 变为了 Using index ,性能
就是比较高的了。
E. 创建索引后,根据 age, phone 进行降序排序
explain select id,age,phone from tb_user order by age desc , phone desc ;

也出现 Using index , 但是此时 Extra 中出现了 Backward index scan ,这个代表反向扫描索
引,因为在 MySQL 中我们创建的索引,默认索引的叶子节点是从小到大排序的,而此时我们查询排序时,是从大到小,所以,在扫描时,就是反向扫描,就会出现 Backward index scan 。 在
MySQL8 版本中,支持降序索引,我们也可以创建降序索引。
F. 根据 phone age 进行升序排序, phone 在前, age 在后。
explain select id,age,phone from tb_user order by phone , age;
排序时 , 也需要满足最左前缀法则 , 否则也会出现 filesort 。因为在创建索引的时候, age 是第一个
字段, phone 是第二个字段,所以排序时,也就该按照这个顺序来,否则就会出现 Using
filesort
F. 根据 age, phone 进行降序一个升序,一个降序
explain select id ,age,phone from tb_user order by age asc ,phone desc;

因为创建索引时,如果未指定顺序,默认都是按照升序排序的,而查询时,一个升序,一个降序,此时就会出现Using filesort
为了解决上述的问题,我们可以创建一个索引,这个联合索引中 age 升序排序, phone 倒序排序
create index idx_user_age_phone on tb_user(age asc,phone desc);

H. 然后再次执行如下 SQL
explain select id,age,phone from tb_user order by age asc , phone desc ;

升序 / 降序联合索引结构图示 :
由上述的测试 , 我们得出 order by 优化原则 :
A. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
B. 尽量使用覆盖索引。
C. 多字段排序 , 一个升序一个降序,此时需要注意联合索引在创建时的规则( ASC/DESC )。
D. 如果不可避免的出现 filesort ,大数据量排序时,可以适当增大排序缓冲区大小
sort_buffer_size( 默认 256k)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2270754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

逐光的黑色羽翼:一位黑色超模的成长之路-中小企实战运营和营销工作室博客

逐光的黑色羽翼:一位黑色超模的成长之路-中小企实战运营和营销工作室博客 在遥远的非洲肯尼亚,有一个小女孩名叫艾拉。她生活在一个小小的部落村庄里,每天伴随着朝阳起床,跟着家人放牧,在广袤无垠的草原上奔跑嬉戏&am…

Java项目实战II基于微信小程序的家庭大厨(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 在快节奏的生活中,家庭聚餐成为了连接亲情…

Github拉取项目报错解决

前言 昨天在拉取github上面的项目报错了,有好几个月没用github了,命令如下: git clone gitgithub.com:zhszstudy/git-test.git报错信息: ssh: connect to host github.com port 22: Connection timed out fatal: Could not rea…

学AI编程的Prompt工程,豆包Marscode

学习链接:Datawhale-AI活动https://www.datawhale.cn/activity/116/23/95?rankingPage1 目录 一、如何使用 二、编写游戏 2.1 创意输入与代码生成 2.2 项目初始化与应用 2.3 创意优化与迭代 三、效果展示 一、如何使用 建议在在vscode上安装marscode插件&a…

NLP CH3复习

CH3 3.1 几种损失函数 3.2 激活函数性质 3.3 哪几种激活函数会发生梯度消失 3.4 为什么会梯度消失 3.5 如何解决梯度消失和过拟合 3.6 梯度下降的区别 3.6.1 梯度下降(GD) 全批量:在每次迭代中使用全部数据来计算损失函数的梯度。计算成本…

计算机网络 (19)扩展的以太网

前言 以太网(Ethernet)是一种局域网(LAN)技术,它规定了包括物理层的连线、电子信号和介质访问层协议的内容。以太网技术不断演进,从最初的10Mbps到如今的10Gbps、25Gbps、40Gbps、100Gbps等,已成…

JavaVue-Get请求 数组参数(qs格式化前端数据)

前言 现在管理系统,像若依,表格查询一般会用Get请求,把页面的查询条件传递给后台。其中大部分页面会有日期时间范围查询这时候,为了解决请求参数中的数组文件,前台就会在请求前拦截参数中的日期数组数据,然…

.e01, ..., .e0n的分卷压缩包怎么解压

用BandiZip,这些分卷压缩中还有一个.exe的文件,这个不是可执行文件,是一个解压缩的开头。 安装好bandiZip后,右键这个.exe文件 点击打开就是开始解压了: 最后解压后是这些。然后一个个再次解压.

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流,并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理:基于文件节点 coulomb_count 实现,计算公式:电流&…

大模型 LangChain 开发框架:Runable 与 LCEL 初探

大模型 LangChain 开发框架:Runable 与 LCEL 初探 一、引言 在大模型开发领域,LangChain 作为一款强大的开发框架,为开发者提供了丰富的工具和功能。其中,Runnable 接口和 LangChain 表达式语言(LCEL)是构…

【Jboss/Windows】Tomcat 8 + JDK 8 升级为 Jboss eap 7 + JDK8

文章目录 下载Jboss eap 7安装包执行standalone.bat修改jdk8不兼容的一些内存空间参数查看端口是否被占用解决端口占用环境变量配置修改项目中的pom文件配置Jboos启动项本地localhost启动测试 更多相关内容可查看 下载Jboss eap 7安装包 Jboss EAP:JBoss Enterpris…

aardio —— 改变按钮文本颜色

import win.ui; /*DSG{{*/ var winform win.form(text"改变按钮颜色示例";right279;bottom239;composited1) winform.add( button{cls"button";text"点这里1";left16;top104;right261;bottom159;fontLOGFONT(h-14);z1}; button2{cls"butto…

Elasticsearch操作笔记版

文章目录 1.ES索引库操作(CRUD)1.mapping常见属性(前提)2.创建索引库3.查询,删除索引库4.修改索引库 2.ES文档操作(CRUD)1.新增文档2.查询、删除文档查询返回的数据解读: 3.修改文档 3.RestClient操作(索引库/文档)(CRUD)1.什么是RestClient2.需要考虑前…

【狂热算法篇】解锁数据潜能:探秘前沿 LIS 算法

嘿,各位编程爱好者们!今天带来的 LIS 算法简直太赞啦 无论你是刚入门的小白,还是经验丰富的大神,都能从这里找到算法的奇妙之处哦!这里不仅有清晰易懂的 C 代码实现,还有超详细的算法讲解,让你轻…

【漫话机器学习系列】033.决策树回归(Decision Tree Regression)

决策树回归(Decision Tree Regression) 决策树回归是一种基于树状结构进行回归分析的监督学习方法。它将输入空间递归地划分为多个区域,并在每个区域内拟合一个简单的常数值,从而对目标变量进行预测。 决策树回归的原理 树的构建…

Vue3中使用 Vue Flow 流程图方法

效果图: 最近项目开发时有一个流程图的功能,需要做流程节点的展示,就搜到了 Vue Flow 这个插件,这个插件总得来说还可以,简单已使用,下边就总结一下使用的方法: Vue Flow官网:https…

ArcGIS JSAPI 高级教程 - 通过RenderNode实现视频融合效果(不借助三方工具)

ArcGIS JSAPI 高级教程 - 通过RenderNode实现视频融合效果(不借助三方工具) 核心代码完整代码在线示例地球中展示视频可以通过替换纹理的方式实现,但是随着摄像头和无人机的流行,需要视频和场景深度融合,简单的实现方式则不能满足需求。 三维视频融合技术将视频资源与三维…

Appllo学习

补充学习: Apollo管理多环境下的配置和踩坑实践 - 简书 Apollo-阿波罗配置中心超详细教程_apllo-CSDN博客 springboot本地local配置覆盖远程Apollo配置(含Apollo配置加载顺序说明)_本地覆盖apollo配置-CSDN博客 Apollo 配置中心详细教程 - 简书 (包含…

React18路由和Vue3路由进行对比

本文将深入比较 React 18 和 Vue 3 路由的不同之处,帮助你更好地理解如何在这两个框架中进行路由管理。希望能对于从 Vue 3 迁移到 React 的开发者,理解这些差异,帮助你更高效地切换框架和构建应用。 1. 路由配置 React 18 的路由配置 Rea…

Windows系统下载、部署Node.js与npm环境的方法

本文介绍在Windows电脑中,下载、安装并配置Node.js环境与npm包管理工具的方法。 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,其允许开发者使用JavaScript编写命令行工具和服务器端脚本。而npm(Node Package Manager)则…