【MySQL】常见的SQL优化方式

news2024/12/25 14:06:59

 

目录

1、插入数据

(1)批量插入

(2)手动提交事务

(3)主键顺序插入

2、主键优化

(1)页分裂

(2)页合并

3、order by 优化

(1)排序方式

(2)order by优化


1、插入数据

数据插入优化其实可以通过几个简单的操作来大幅提高效率。

以下是几种常见的优化方法:

(1)批量插入

        如果我们要一次性插入很多数据,而每条数据都用单独的 INSERT 语句,那会很慢。最好使用批量插入,把多条数据写在一条 INSERT 语句里。这样数据库只需要一次性处理多个数据,而不是每次都处理一条,速度会快很多。

INSERT INTO tb_test VALUES (1, 'Tom'), (2, 'Cat'), (3, 'XiaoTao');

(2)手动提交事务

        默认情况下,每次插入一条数据,数据库都会自动提交一个事务。如果我们有很多条数据要插入,手动控制事务可以大幅减少数据库的事务开销。也就是说,先插入一批数据,然后手动提交,而不是每插入一条就提交一次。

START TRANSACTION;

INSERT INTO tb_test VALUES (1, 'Tom'), (2, 'Cat'), (3, 'XiaoTao');
INSERT INTO tb_test VALUES (4, 'Tom'), (5, 'Cat'), (6, 'XiaoTao');
INSERT INTO tb_test VALUES (7, 'Tom'), (8, 'Cat'), (9, 'XiaoTao');

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

(4)大批量插入数据 - 使用 LOAD DATA 

        当需要一次插入非常大量的数据时,INSERT 语句的效率就很低了。这时可以使用 MySQL 提供的 LOAD DATA 指令。它能直接从文件中批量加载数据,速度比普通的 INSERT 快得多。举个例子,插入 100 万条数据,INSERT 可能需要十几分钟,而 LOAD DATA 只需要十几秒。使用 LOAD DATA 指令时也是主键顺序插入性能高于乱序插入

具体操作步骤:

  • 首先,用 mysql --local-infile 命令连接数据库,开启从本地加载文件的功能。
  • 然后,设置全局参数 local_infile=1,允许加载本地文件。
  • 最后,用类似下面的 LOAD DATA 命令导入数据:
LOAD DATA LOCAL INFILE '/root/sql1.log' 
INTO TABLE `tb_user` 
FIELDS TERMINATED BY ', ' 
LINES TERMINATED BY '\n';

        这个SQL命令的意思就是:从 /root/sql1.log 文件中读取数据,按照逗号分隔每个字段,按照换行符分隔每条记录,批量插入到 tb_user 表里。fields terminated by ', ' 的意思是每一个字段之间使用 ', ' 分隔,lines terminated by '\n' 的意思是每一行数据用 '\n' 分隔

2、主键优化

        主键的设计对数据库性能影响非常大,尤其是在InnoDB存储引擎中,表是按照主键顺序存储的,合理的主键设计能有效避免性能问题

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

        InnoDB的逻辑存储结构:最外层是表空间(Tablespace),表空间中存储的是一个一个段(Segment),段当中存放的是一个一个区(Extent),一个区的大小是固定的1M,在区当中存放的是一个一个的页(Page),页当中存放的是一个一个的行(Row),行当中就是存放着具体的字段值。页是InnoDB磁盘管理的最小单元,一个页的大小默认是16K,也就是一个区当中可以包含64个页

(1)页分裂

        页可以为空,也可以填充一半,也可以填充100%。每个页包含了2至N行数据,具体包含多少行数据取决于每行的大小(如果一行数据过大,会行溢出),每行数据根据主键排列。

主键顺序插入:当我们按照顺序插入数据时,页的填充不会导致分裂。这意味着在插入新数据时,InnoDB 会自动将数据放入适当的页,不会造成额外的结构调整。

主键乱序插入:如果插入的是乱序数据,B+ 树必须在合适的位置插入新数据,这可能导致现有页被填满或溢出,从而触发页分裂。发生页分裂时,InnoDB 会将当前页中的部分数据移动到一个新的页,以保持主键的顺序。下面的过程就是页分裂

(2)页合并

        当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。

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

比如:下面图一第二页中的删除记录达到了50%,然后就页合并变成了图二,再插入id为20的数据时就插入到新的页中

提示:MERGE THRESHOLD:合并页的阈值,可以自己设置,在创建表或者创建索引时指定。

(3)主键设计原则

根据上面对主键的了解,主键设计原则如下

(一)满足业务需求的情况下,尽量降低主键的长度。因为对于一张表来说,主键(聚集)索引只有一个,但是二级索引可以有多个,在二级索引的叶子节点中存放的就是数据的主键,所以说如果主键比较长,二级索引比较多,那么会占用大量的磁盘空间,而且在搜索时也会耗费大量的磁盘IO,所以要尽量降低主键的长度。

(二)插入数据时,尽量选择顺序插入,选择使用 AUTOINCREMENT 自增主键。因为如果是顺序插入就会使第一个页数据插入满了就插入下一个页,不会发生页分裂的现象。

(三)尽量不要使用UUID做主键或者是其他自然主键,如身份证号。因为UUID生成的主键是无序的,在插入数据时就是乱序插入的,就可能会存在页分裂的现象。还有一点就是主键使用UUID或身份证号,主键的长度就会长,在检索的时候就会耗费大量的磁盘IO。

(四)主键的唯一性决定了它不应该经常被修改。修改主键不仅要调整数据,还要重构相关的索引结构,这会造成较大的性能开销。所以,尽量避免在业务操作中对主键进行修改。这里的修改主键是指重新指定主键字段。

3、order by 优化

(1)排序方式

在MySQL中,排序主要有两种方式:Using filesort 和 Using index。

Using filesort:当排序无法通过索引直接返回结果时,MySQL会先通过索引或全表扫描获取满足条件的数据行,然后在排序缓冲区(sort buffer)中完成排序。这种排序就是Using filesort。

Using index:当数据可以通过有序索引直接返回时,不需要额外的排序操作,这种情况就是Using index,效率更高。

        如果根据某个字段进行排序,并且该字段有相应的索引,MySQL会采用Using index的方式;反之,没有索引时,就会用到Using filesort。创建索引时,索引的默认排序为升序,

        举个例子:如果有一个包含 age 和 phone 字段的联合索引,并且按这两个字段进行升序或降序排序,通常会使用Using index。

# 没有创建索引时,根据age,phone进行排序
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age, phone;

# 创建索引
CREATE INDEX idx_user_age_phone_aa ON tb_user(age, phone);

# 创建索引后,根据age,phone进行升序排序
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age, phone;

# 创建索引后,根据age,phone进行降序排序
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age DESC, phone DESC;

        但是,如果想让 age 按升序排序,phone 按降序排序,那么MySQL会使用Using index加Using filesort。要避免filesort,可以创建一个 age 升序、phone 降序的联合索引。

# 根据age升序、phone降序排序
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age ASC, phone DESC;

# 创建age升序、phone降序的联合索引
CREATE INDEX idx_user_age_phone_ad ON tb_user(age ASC, phone DESC);

# 创建索引后,再次根据age升序、phone降序排序
EXPLAIN SELECT id, age, phone FROM tb_user ORDER BY age ASC, phone DESC;

        创建age、phone的联合索引,age和phone都为升序的索引结构如下:先根据age进行升序排序,当age相同时再根据phone进行升序排序

        创建age、phone的联合索引,age为升序、phone为降序的索引结构如下:先根据age进行升序排序,当age相同时再根据phone进行降序排序

(2)order by优化

(一)合理建立索引:根据排序字段创建合适的索引。如果是多个字段的排序,遵循最左前缀法则,确保索引能最大程度利用。

(二)尽量使用覆盖索引:避免SELECT *,因为如果查询的字段不在索引里,MySQL需要回表查询,排序依然会使用 filesort 。

(三)注意联合索引的排序规则:如果多字段排序时一个字段升序、另一个降序,需要在创建联合索引时明确 ASC/DESC 顺序。

(四)增大sort buffer size:如果无法避免filesort,并且数据量很大,可以适当增大排序缓冲区(sort buffer size,默认是256k)。否则,当数据超出缓冲区时会进行磁盘排序,影响性能。

推荐:

【数据结构】二叉查找树和平衡二叉树,以及二者的区别_平衡树和二叉搜索树-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/m0_65277261/article/details/136137098?spm=1001.2014.3001.5501【数据结构】前缀树的模拟实现_前缀树实现-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/m0_65277261/article/details/136086068?spm=1001.2014.3001.5501

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

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

相关文章

探索有向图深度优先搜索的路径与时间的猜想:反例研究

探索有向图深度优先搜索的路径与时间的猜想:反例研究 引言深度优先搜索(DFS)猜想描述反例构造图结构提供一个DFS遍历顺序伪代码具体的DFS遍历时间戳记录分析C语言实现代码解释运行结果结论引言 在图论中,深度优先搜索(DFS)是一种重要的图遍历算法,被广泛应用于寻找路径…

VMware ESXi 8.0U3b macOS Unlocker OEM BIOS 2.7 标准版和厂商定制版

VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版 ESXi 8.0U3 标准版,Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科)、Hitachi (日立)、Fujitsu (富士通)、NEC (日电) 定制版、Huawei (华为) OEM 定制版 请访问…

【讲解+样例】使用opencv对aruco Markers识别

aruco标记与传统棋盘格功能相似,但是更快更便捷。棋盘格使用移步:【鱼眼+普通相机】相机标定 一、 aruco简介 aruco又称为aruco标记、aruco标签、aruco二维码。ArUco 标记通常是正方形的黑白图案。由黑色边框和内部的二进制矩阵组成。内部矩…

63.HDMI显示器驱动设计与验证-彩条实验

(1)常见的视频传输接口有三种: VGA 接口、 DVI 接口和 HDMI 接口,目前的显示设备都配有这三种视频传输接口。三类视频接口的发展历程为 VGA→DVI→HDMI。其中 VGA 接口出现最早,只能传输模拟图像信号; 随后…

CSS 背景属性概览:颜色、图像、位置、组合及透明

目录 非 VIP 用户可前往公众号回复“css”进行免费阅读 background - color background - image background - repeat background - position background - attachment background组合 背景透明 非 VIP 用户可前往公众号回复“css”进行免费阅读 background - color …

Stable Diffusion绘画 | SDXL模型的优缺点及模型推荐

现在 SD 已经开始全面进入 SDXL 的高分辨率时代。 SDXL 模型的优点 学习参数最多的模型:参数总量超过100亿,可对标 Midjourney 分辨率提升4倍:底模分辨率直接为 1024 x 1024 多出 Refiner 采样重构器:能增加更多的细节 更强的提示…

2024上海工博会,正运动展位新品与应用方案(二)

上海,9月26日,上海工博会已成功开展三天。正运动展位(6.1H-E261)依然人气高涨,吸引了众多专业观众和行业同仁的关注。精彩仍在继续~ 展会现场 01 多元工业应用场景方案展示 DEMO应用演示在本次展会上&…

云打包p12苹果证书和profile文件在线制作流程

使用hbuilderx的uniapp框架,除了开发小程序外,还可以打包出原生的安卓或苹果应用。 假如是打包安卓应用个,则需要安卓证书。 而假如打包ios应用,则需要p12格式的苹果证书和苹果证书的profile文件。其中苹果证书可以理解为基于非…

c++----继承(初阶)

大家好呀,今天我们也是多久没有更新博客了,今天来讲讲我们c加加中的一个比较重要的知识点继承。首先关于继承呢,大家从字面意思看,是不是像我们平常日常生活中很容易出现的,比如说电视剧里面什么富豪啊,去了…

CDF 累积分布函数图 怎么看

以上图为例,图中有五个数据集,每条曲线代表每个数据集中流的数量,然后我以蓝色的线条为例去解释怎么看这个图。 红色的方框的点说明,dataset-1中流数量少于500的app占全部app的20%;紫色的方框的点说明,da…

win10下NAT 端口转发及ssh VMware ubuntu24虚拟机

问题:win10无法访问VMware ubuntu24虚拟机。ping不通,ssh不通。 现象: 无法设置网桥模式。原因不明。win10 网络连接 中没有vmnet0 网桥模式。win10 网络连接 中,有vmnet8的NAT模式,有vmnet1的仅主机模式。VMware ub…

【Redis】Linux下安装配置及通过C++访问Redis

文章目录 一、Linux Centos 7.0版本下的安装及配置二、通过C访问Redis 一、Linux Centos 7.0版本下的安装及配置 通过源来安装,此次安装的版本为 redis 5.0 的,要通过其他源进行安装,首先安装 scl 源 yum install centos-release-scl-rh再安…

【LeetCode】每日一题 2024_9_26 数组元素和与数字和的绝对差(模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动! 题目:数组元素和与数字和的绝对差 代码与解题思路 func differenceOfSum(nums []int) int {sum1, sum2 : 0, 0for _, v : range nums {sum1 vfor v > 0 {sum2 v%10v / 10}}return sum1-s…

教师工作量在线管理服务

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…

dockerfile部署springboot项目(构建镜像:ebuy-docker:v1.0)

文章目录 1、docker部署Mysql2、dockerfile构建镜像1.1、在idea中导入课件中的项目资料\day01\ebuy-docker1.2、修改项目application.yml数据库连接参数1.3、启动项目访问测试:http://localhost:8081/1.4、执行mvn package命令进行项目打包1.5、虚拟机中新建目录/op…

高性能计算秘密武器:NVIDIA B100与B200如何让你的HPC性能飙升?

嘿,各位科技界的狂热粉丝、AI领域的探索先锋,你们是否正站在高性能计算(HPC)的十字路口,寻找那把能开启全新纪元的钥匙?今天,就让我带你深入剖析NVIDIA的最新力作——B100与B200,一同…

C++结尾

面试题 1.什么是虚函数?什么是纯虚函数 在定义函数时前面加virtual。虚函数是为了,父子类中只有一个该函数。如果在子类重写虚函数,那么用的就是子类重写的虚函数;如果子类没有重写虚函数,那么调用的是父类继承的虚函…

【JAVA开源】基于Vue和SpringBoot的网上租赁系统

本文项目编号 T 050 ,文末自助获取源码 \color{red}{T050,文末自助获取源码} T050,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计5.4.1 用…

生信软件37 - 基于测序reads的变异进行单倍型分型工具WhatsHap

1. WhatsHap简介 WhatsHap是一种使用DNA测序reads的基因组变异进行定相(分型)的软件,即基于reads的定相或单倍型组装,特别适用于长reads (三代测序数据),但也兼容短reads的定相。 Whatshap特点…

Ubuntu22.04安装cudnn详细步骤

下载指定版本的cudnn https://developer.nvidia.com/rdp/cudnn-archive#a-collapse804-111 安装 sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.7.29_1.0-1_amd64.deb 根据上步提示: sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.7.29/cudnn-local-08A7D361-…