Mysql进阶-SQL优化篇

news2024/11/25 20:19:27

插入数据

insert

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

  •  批量插入数据
一条insert语句插入多个数据,但要注意,每个insert语句最好插入500-1000行数据,就得重新写另一条insert语句
Insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
  • 手动控制事务

我们可以手动控制事务,在多条insert语句之间收起开启和提交事务,防止一次insert之后就提交事务浪费性能

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

大批量插入数据

如果一次性需要插入大批量数据(比如: 几百万的记录),使用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' ;

主键优化

数据组织方式

 在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表 (index organized table IOT)。

 行数据,都是存储在聚集索引的叶子节点上的。在InnoDB引擎中,数据行是记录在逻辑结构 page 页中的,而每一个页的大小是固定的,默认16K。 那也就意味着, 一个页中所存储的行也是有限的,如果插入的数据行row在该页存储不小,将会存储到下一个页中,页与页之间会通过指针连接。

 

 主键顺序插入效果

  1. 从磁盘中申请页, 主键顺序插入

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

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

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

 主键乱序插入效果

页分裂

假如1#,2#页都已经写满了,存放了如图所示的数据

 此时再插入id为50的记录,因为要维持主键在内存的顺序,应该插入在47之后,47所在的页所剩的内存并不足以放下50这条记录,此时会开辟一个新的页

但是并不会直接将50存入3#页,而是会将1#页后一半的数据,移动到3#页,然后在3#页,插入50。

 

 移动数据,并插入id为50的数据之后,那么此时,这三个页之间的数据顺序是有问题的。 1#的下一个 页,应该是3#, 3#的下一个页是2#。 所以,此时,需要重新设置链表指针。

页合并 

目前表中已有数据的索引结构(叶子节点)如下:

当我们对已有数据进行删除时,具体的效果如下: 当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。跟操作系统删除磁盘空间是类似的,只是逻辑删除,允许其它程序对该空间的数据进行覆盖。

在我们删除记录达到MERGE_THRESHOLD(默认为页的50%,可自己设置),InnoDB会开始寻找最靠近的页(前 或后)看看是否可以将两个页合并以优化空间使用。

 

 删除数据,并将页合并之后,再次插入新的数据21,则直接插入3#页

 主键设计原则

  • 满足业务需求的情况下,尽量降低主键的长度。
  • 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
  • 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
  • 业务操作时,避免对主键的修改。

 order by优化

MySQL的排序,有两种方式:

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

Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要 额外排序,操作效率高。

对于以上的两种排序方式,Using index的性能高,而Using filesort的性能低,我们在优化排序操作时,尽量要优化为 Using index

 执行排序SQL,由于 age, phone 都没有索引,所以此时再排序时,出现Using filesort, 排序性能较低

那我们可以根据我们的业务,如果我们总是需要根据这两个字段来order by排序,那我们可以完全可以为phone和age建立联合索引

create index idx_user_age_phone_aa on tb_user(age,phone);

建立索引之后就优化为Using index

 这时候如果倒序查,也出现Using index, 但是此时Extra中出现了 Backward index scan,这个代表反向扫描索引,因为在MySQL中我们创建的索引,默认索引的叶子节点是从小到大排序的,而此时我们查询排序 时,是从大到小,所以,在扫描时,就是反向扫描,就会出现 Backward index scan。 在 MySQL8版本中,支持降序索引,我们也可以创建降序索引。

 这时候我们需要建立倒序索引,就可优化成Using index,只要我们的排序顺序有对应的索引顺序,就可优化成Using index

优化原则

A. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。

B. 尽量使用覆盖索引。

C. 多字段排序, 一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)。

D. 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小 sort_buffer_size(默认256k)。

 group by优化

没有索引的情况,进行分组,可以看见用到了临时表,性能较差

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

 再执行前面相同的SQL查看执行计划。已经优化成using index,如果是单单根据age分组,最后还是会走临时表,group by也符合最左前缀法则

在分组操作中,我们需要通过以下两点进行优化,以提升性能:

A. 在分组操作时,可以通过索引来提高效率。

B. 分组操作时,索引的使用也是满足最左前缀法则的。

limit优化

在数据量比较大时,如果进行 limit 分页查询,在查询时,越往后,分页查询效率越低。
通过测试我们会看到,越往后,分页查询效率越低,这就是分页查询的问题所在。
因为,当在进行分页查询时,如果执行 limit 2000000,10 ,此时需要MySQL排序前2000010 记录,仅仅返回 2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大。
优化思路 :
一般分页查询时,通过创建覆盖索引能够比较好地提高性能,也可以通过覆盖索引加子查
询形式进行优化。我们也可以通过limit来查询id,由于id是主键索引,效率较高,通过子查询的形式作为临时表,返回排序好的id表,来进行多表联查,总的查询也是走的id索引,性能较高

 count优化

概述

MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个
数,效率很高; 但是如果是带条件的 countMyISAM 也慢
InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出
来,然后累积计数。这样子效率低

 主要的优化思路:

自己计数,可以借助于redis这样的数据库进行,redis本身就有自增长的键,可以满足这一业务,但是如果是带条件的count又比较麻烦了,可以说这一问题还是比较麻烦的

 count用法

count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是
NULL,累计值就加 1 ,否则不加,最后返回累计值。
用法: count * )、 count (主键)、 count (字段)、 count (数字)
按照效率排序的话, count( 字段 ) < count( 主键 id) < count(1) ≈ count(*) ,所以
量使用 count(*)。
count
含义
count( 主键)
InnoDB 引擎会遍历整张表,把每一行的 主键 id 值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加( 主键不可能为 null)
count( 字 段)
没有not null 约束 : InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null ,不为 null ,计数累加。
有not null 约束 InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加
count(
)
InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字 “1” 进去,直接按行进行累加。
count(*)
InnoDB 引擎 并不会把全部字段取出来 ,而是专门做了优化,不取值,服务层直接按行进行累加

update优化

当我们执行此句update语句时,锁住的是这一行数据。

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

如果执行此句sql执行的是表锁
update course set name = 'SpringBoot' where name = 'PHP' ;

原因是

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁 升级为表锁 。我们进行dml操作时,尽量根据索引为查找条件,避免升级成表锁,影响并发

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

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

相关文章

YOLO系列环境配置及训练

目录 前言 一、下载所需 1、Anaconda安装 2、NVIDIA 驱动程序安装 3、CUDA安装 4、CUDNN下载及配置 二、环境配置 1、虚拟环境创建 2、Pytorch安装 3、pycharm环境切换及剩余库的安装 4、YOLO代码的测试及训练配置步骤 &#xff08;1&#xff09;测试 &#xff08…

国际阿里云香港服务器!!!

轻量应用服务器&#xff08;Simple Application Server&#xff09;是可以快速搭建且易于管理的轻量级云服务器&#xff0c;面向单台服务器提供了一键部署应用、一站式域名解析、安全管理以及运维监控等服务。轻量应用服务器操作简单便捷&#xff0c;能让您快速上手部署简单的应…

AVL树

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;AVL树概念&#x1f449;&am…

专业媒体播放软件Movist Pro中文

Movist Pro是一款专为Mac用户设计的专业媒体播放器。它支持广泛的视频和音频格式&#xff0c;包括MP4、AVI、MKV等&#xff0c;并提供了高级播放控件和定制的视频设置。其直观易用的用户界面&#xff0c;使得播放高清视频更为流畅&#xff0c;且不会卡顿或滞后。同时&#xff0…

海康Visionmaster-全局触发:使用全局触发功能执行流 程的方法

我们这里以 TCP 通讯为例&#xff0c;视觉作为 TCP 服务端&#xff0c;与视觉交互的第三方设备作为 TCP 客户端。当 TCP 客户端连接上视觉服务端后&#xff0c;客户端发送字符串 T1,视觉执行流程 1&#xff1b; 客户端发送字符串 T2&#xff0c;视觉执行流程 2。 这样的需求我…

在 CelebA 数据集上训练的 PyTorch 中的基本变分自动编码器

摩西西珀博士 一、说明 我最近发现自己需要一种方法将图像编码到潜在嵌入中&#xff0c;调整嵌入&#xff0c;然后生成新图像。有一些强大的方法可以创建嵌入或从嵌入生成。如果你想同时做到这两点&#xff0c;一种自然且相当简单的方法是使用变分自动编码器。 这样的深度网络不…

Markdown语法教程

Markdown&#xff1a;一种轻量级语言&#xff0c;有简洁的编写方式&#xff0c;能够提高大家的工作效率。 一、标题 1.1 标题 标题的编写格式以#号开始&#xff0c;分别表示h1 ~ h6&#xff0c;注意&#xff1a;# 后面有空格&#xff01; # 一级标题 ## 二级标题 ### 三级标题…

K8s学习笔记——认识理解篇

1. K8s诞生背景 回顾应用的部署&#xff0c;经历了以下几个阶段&#xff1a; 传统部署&#xff1a;物理服务器上运行应用程序。虚拟机部署&#xff1a;物理服务器上安装虚拟机&#xff0c;在虚拟机上运行应用程序。容器部署&#xff1a;物理服务器上安装容器运行时&#xff0…

MINIO minio 安装 报错 问题

minio MINIO 安装 报错 问题 前言问题1问题产生原因分析解决方案 问题2原因分析解决方案 问题3问题产生原因分析解决方案 问题4问题产生 原因分析解决方案 问题5问题产生 原因分析解决方案 关键词&#xff1a; 1: WARNING: MINIO_ACCESS_KEY and MINIO_SECRET_KEY are deprecat…

全能数据分析软件 Tableau Desktop 2019 mac中文版功能亮点

Tableau Desktop 2019 mac是一款专业的全能数据分析工具&#xff0c;可以让用户将海量数据导入并记性汇总&#xff0c;并且支持多种数据类型&#xff0c;比如像是编程常用的键值对、哈希MAP、JSON类型数据等&#xff0c;因此用户可以将很多常用数据库文件直接导入Tableau Deskt…

2019 ICPC 银川题解(A)

赛时没发挥好6题金尾&#xff08;rank38&#xff09;&#xff0c;剩下很多能写的题&#xff0c;其中四个dp&#xff0c;傻眼ing A Girls Band Party&#xff08;背包&#xff09; 有点迷惑的题&#xff0c;当时看只要 5 5 5 张牌一下子想到暴力枚举&#xff0c;结果发现是不…

【漏洞复现】Redis未授权

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、影响版本1.3、漏洞复现环境搭建写入计划任务获取反弹shell利用SSH写公钥&#xff0c;免密登陆利用Redis写WebShell 3、检测未授权访问漏洞检测工具参考 1.1…

《 Hello 算法 》 - 免费开源的数据结构与算法入门教程电子书,包含大量动画、图解,通俗易懂

这本学习算法的电子书应该是我看过这方面最好的书了&#xff0c;代码例子有多种编程语言&#xff0c;JavaScript 也支持。 《 Hello 算法 》&#xff0c;英文名称是 Hello algo&#xff0c;是一本关于编程中数据解构和算法入门的电子书&#xff0c;作者是毕业于上海交通大学的…

零代码复现-TCGA联合GEO免疫基因结合代谢基因生信套路(三)

前面的分析中&#xff0c;整理好的关键基因集表达谱矩阵&#xff0c;接下来就准备分子亚型的相关分析。 六、一致性聚类构建分子亚型 在6.TCGA和GEO差异基因获取和预后数据的整理\TCGA文件中获取文件 准备一个生存数据和表达谱矩阵&#xff0c;这里需要注意的是&#xff0c;…

基于Jenkins实现接口自动化持续集成,学完涨薪5k

一、JOB项目配置 1、添加描述 可选选项可填可不填 2、限制项目的运行节点 节点中要有运行环境所需的配置 节点配置教程&#xff1a;https://blog.csdn.net/YZL40514131/article/details/131504280 3、源码管理 需要将脚本推送到远程仓库中 4、构建触发器 可以选择定时构建…

【爬虫实战】用python爬取微博任意关键词搜索结果、exe文件

项目功能简介&#xff1a; 1.交互式配置&#xff1b; 2.两种任意关键词来源&#xff08;直接输入、本地关键词文件&#xff09;&#xff1b; 3.自动翻页(无限爬取)&#xff1b; 4.指定最大翻页页码&#xff1b; 5.数据保存到csv文件&#xff1b; 6.程序支持打包成exe文件…

Go类型嵌入介绍和使用类型嵌入模拟实现“继承”

Go类型嵌入介绍和使用类型嵌入模拟实现“继承” 文章目录 Go类型嵌入介绍和使用类型嵌入模拟实现“继承”一、独立的自定义类型二、继承三、类型嵌入3.1 什么是类型嵌入 四、接口类型的类型嵌入4.1 接口类型的类型嵌入介绍4.2 一个小案例 五、结构体类型的类型嵌入5.1 结构体类…

视频视觉效果制作After Effects 2023 MacOS中文

After Effects 2023是一款业界领先的动态图形和视觉特效软件。它提供了强大的工具集&#xff0c;帮助用户创建引人入胜的视觉效果、动态图形和电影级特效。新的版本带来了更快的渲染速度、增强的图像处理和优化的工作流程&#xff0c;使用户能够更高效地工作。无论您是在电影、…

Kotlin 进阶函数式编程技巧

Kotlin 进阶函数式编程技巧 Kotlin 简介 软件开发环境不断变化&#xff0c;要求开发人员不仅适应&#xff0c;更要进化。Kotlin 以其简洁的语法和强大的功能迅速成为许多人进化过程中的信赖伙伴。虽然 Kotlin 的初始吸引力可能是它的简洁语法和与 Java 的互操作性&#xff0c…

idea文件比对

idea文件比对 1.项目内的文件比对2.项目间的文件比对3. 剪切板对比4. 版本历史(不同分支和不同commit)对比 1.项目内的文件比对 在项目中选择好需要比对的文件(类)&#xff0c;然后选择Compare Files Mac下的快捷键是Commandd&#xff0c; 这样的比对像是git冲突解决一样 …