MySQL—SQL优化详解(上)

news2024/11/25 6:42:54

♥️作者:小刘在C站

♥️个人主页: 小刘主页 

♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!

♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术

♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!

前言

本章讲解SQL语言中的优化

目录

SQL优化

1 插入数据

1.1 insert

1). 优化方案一

2). 优化方案二 

3). 优化方案三

1.2 大批量插入数据

示例演示:

A. 创建表结构

B. 设置参数

C. load加载数据

2 主键优化

1). 数据组织方式

2). 页分裂

A. 主键顺序插入效果

 B. 主键乱序插入效果

3). 页合并

4). 索引设计原则


SQL优化

1 插入数据

1.1 insert

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

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

1.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就完成了,性能很好。

我们看到,插入100w的记录,17s就完成了,性能很好。

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做主键或者是其他自然主键,如身份证号。

业务操作时,避免对主键的修改。

 

♥️关注,就是我创作的动力

♥️点赞,就是对我最大的认可

♥️这里是小刘,励志用心做好每一篇文章,谢谢大家

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

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

相关文章

万物的算法日记|第三天

笔者自述: 一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结&am…

FasterTransformer 001 start up

FasterTransformer Faster Transformer是一个Transformer单层前向计算的高效实现。一个函数由多个OP组合实现。每一个基本OP都会对应一次GPU kernel的调用,和多次显存读写。OP融合可以降低GPU调度和显存读写,进而提升性能。在Faster Transformer&#x…

位姿估计 | 目标体坐标系相对于相机坐标系的位姿估计及其Python代码

目录 引言技术流程1. PNP介绍2. ICP介绍a. 利用ICP求解目标相对相机的位姿b. 利用ICP求解相机帧间运动 Python代码 引言 本文接着分享空间目标位姿跟踪和滤波算法中用到的一些常用内容,希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章:位…

Redis 之Jedis 加springboot整合Redis

Jedis API 文档 在线文档: https://www.mklab.cn/onlineapi/jedis/ Jedis 介绍 Jedis 工作示意图 Java 程序操作Redis 的工具 示意图 Jedis 操作Redis 数据 快速入门 创建maven 项目 注意二步是路径配置自己想放哪里 三步是 定义包的层次结构 嫌弃麻烦的也可以不设置 …

chatgpt赋能python:Python编程技巧:如何横着打印差数列

Python编程技巧:如何横着打印差数列 随着互联网时代的到来,SEO已成为企业推广和营销的重要手段。而作为一名具有10年Python编程经验的工程师,我发现Python编程技巧的学习和应用也可以帮助企业优化SEO排名。本文将从实际项目需求出发&#xf…

如何实现Http请求报头的自动转发之设计

HeaderForwarder组件不仅能够从当前接收请求提取指定的HTTP报头,并自动将其添加到任何一个通过HttpClient发出的请求中,它同时也提供了一种基于Context/ContextScope的编程模式是我们可以很方便地将任何报头添加到指定范围内的所有由HttpClient发出的请求…

基于Java家政服务网站系统设计实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

opencv人与摄像头距离、角度检测

参考: https://chtseng.wordpress.com/2018/09/18/%E5%A6%82%E4%BD%95%E4%BC%B0%E7%AE%97%E5%89%8D%E6%96%B9%E4%BA%BA%E7%89%A9%E7%9A%84%E8%B7%9D%E9%9B%A2/ WeChat_20230611160620 1、cv2加载摄像头慢解决方法,单独重新cv2.VideoCapture() https://b…

新《终结者》电影剧本或交由 ChatGPT 书写

据外媒报道,詹姆斯・卡梅隆透露他正在创作下一部《终结者》电影的剧本,他同时表示新剧本的灵感得益于 OpenAI 的 ChatGPT。 打开豆瓣,1984年10月上映的那部「终结者」评分依然在8分以上。而后,终结者系列的电影不断上新&#xff…

基于Java房屋租售网站设计实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

考研计算机组成思维导图总结(408,833,834)

需要思维导图文件和图片的可以去我的Github上寻找,这份思维导图参考23年王道机组,同时添加了一部分833,834需要知识点。 注意:最后的机组知识点仍要以学院进行对照,这里只是提供参考 思维导图pdf和知识点图片 文章目…

<Linux> 《SUSE Linux 中SSH安全加固》

《SUSE Linux 中SSH安全加固》 1 说明2 安全加固2.1 更改 ssh 默认端口2.2 限制 ROOT 远程登陆2.3 修改默认登录时间2.4 升级旧版本2.5 当用户处于非活动时断线2.6 修改加密协议版本2.7 限制 IP 登录2.8 允许或禁止指定用户和组登录2.9 限制监听 IP2.10 最后修改配置文件的属性…

【JVM 监控工具】JVisualVM的使用

文章目录 前言二、启动JVisualVM三、安装插件四、使用 前言 JVisualVM是一个Java虚拟机的监控工具,要是需要对JVM的性能进行监控可以使用这个工具哦 使用这个工具,你就可以监控到java虚拟机的gc过程了 那么,这么强大的工具怎么下载呢&…

【HBZ分享】FactoryBean的应用 与 BeanFactroyPostProcessor的应用 与 BeanPostProcesser的应用

FactoryBean的应用实战 需要写一个A类来实现FactoryBean实现FactoryBean的3个方法,即getOject(), getObjectType(), isSingleton()注意:在通过xml的【 】标签或者通过注解方式将A类注入容器的时候,返回的实例不是A类,而是T类&…

HTML 基础

目录 HTML 结构 1.认识 HTML 标签 HTML 文件基本结构 标签层次结构 HTML 常见标签 注释标签 标题标签: h1-h6 段落标签: p 换行标签: br 格式化标签 图片标签: img 关于目录结构: 超链接标签: a 链接的几种形式: 表格标签 合并单元格 列表标签 表单标签 form …

【头歌-Python】Python第九章作业(初级)第 1、2、4 关

第1关:绘制温度曲线 任务描述 附件中是某月每天的最高温度和最低温度数据,请绘制本月的高温曲线(红色、圆点标记坐标)和低温曲线(蓝色、星号标记坐标),线型、刻度如输出示例所示,线…

Rust每日一练(Leetday0031) 解码方法、复原 IP 地址

目录 91. 解码方法 Decode Ways 🌟🌟 93. 复原 IP 地址 Restore IP Addresses 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 91. …

chatgpt赋能python:Python如何求平均

Python如何求平均 Python是一种非常流行的编程语言,它被广泛应用于各种领域,包括科学计算、数据分析、Web开发等。在这篇文章中,我们将介绍如何使用Python求平均值。 什么是平均数 平均数,也称为均值,是指一组数据的…

chatgpt赋能python:Python怎么求平均值?全面解析平均值计算方法

Python怎么求平均值?全面解析平均值计算方法 作为一种简洁易用的计算机编程语言,Python的应用范围已经越来越广泛。在Python中,我们可以轻松地进行各种统计和计算工作,其中求平均值是最常见的计算之一。在本文中,我们…