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

【MySQL】常见的SQL优化方式(一)

目录

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

相关文章:

【MySQL】常见的SQL优化方式(一)

目录 1、插入数据 (1)批量插入 (2)手动提交事务 (3)主键顺序插入 2、主键优化 (1)页分裂 (2)页合并 3、order by 优化 (1)排…...

【重点】使用axios.request.put上传文件,报错分析

使用axios的put方法上传文件时,如果遇到错误,可能的原因有以下几点: 跨域问题:如果请求的URL与当前页面的域名不同,可能会触发跨域问题。解决方法是在服务器端设置允许跨域请求,如设置CORS(跨域…...

最新最全的阿里大模型面试真题!看到就是赚到

前言 随着人工智能技术的飞速发展,计算机视觉(CV)、自然语言处理(NLP)、搜索、推荐、广告推送和风险控制等领域的岗位越来越受到追捧,掌握大型模型技术已成为这些岗位的必备技能。然而,目前公开…...

使用Docker快速本地部署RSSHub结合内网穿透访问RSS订阅源

文章目录 前言1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 前言 今天和大家分享的是如何在本地快速简单部署Rsshub工具,并结合cpolar内网穿透工具使用公网地址远…...

win10系统K8S安装教程

准备工作 电脑硬件:支持虚拟化的CPU,内存最好在32G以上,16G也可以操作系统:window10 专业版 1 开启虚拟化 1.1 BIOS 由于主板和CPU的品牌不太一样,这里的操作仅供参考,以Intel的平台为例: …...

C#和Python共享内存技术

我这里做一个简单的示例 1.C#写入内存的方法,FileName是内存共享的名字 t是内存size public static void SaveGluePLYToMemory(string FileName, string msg){try{ long t 100;// SetMemorySize(msg);// 100;//# 创建内存块,test1,其他语言利用这个内存…...

Java每日面试题(JVM)(day15)

目录 Java对象内存布局markWord 数据结构JDK1.8 JVM 内存结构JDK1.8堆内存结构GC垃圾回收如何发现垃圾如何回收垃圾 JVM调优参数 Java对象内存布局 markWord 数据结构 JDK1.8 JVM 内存结构 程序计数器: 线程私有,记录代码执行的位置. Java虚拟机栈: 线程私有&#…...

在 CentOS 8 上安装和部署 OpenSearch 2.17 的实战指南20240924

在 CentOS 8 上安装和部署 OpenSearch 2.17 的实战指南 引言 随着数据的快速增长,企业对高效搜索和分析工具的需求也在不断增加。OpenSearch 是由社区主导的搜索和分析引擎,它为大规模数据索引、日志分析、全文检索等场景提供了强大的支持。在这篇博客…...

青动CRM-E售后V2.0.4

CRM售后管理系统,旨在助力企业销售售后全流程精细化、数字化管理,主要功能:客户、合同、工单、任务、报价、产品、库存、出纳、收费,适用于:服装鞋帽、化妆品、机械机电、家具装潢、建材行业、快销品、母婴用品、办公用…...

免杀对抗—C++混淆算法shellcode上线回调编译执行

前言 上次讲了python混淆免杀,今天讲一下C混淆免杀。其实都大差不差的,也都是通过各种算法对shellcod进行混淆免杀,只不过是语言从python换成c了而已。 实验环境 测试环境依旧是360、火绒、WD还有VT。 shellcode上线 下面是最基本几个sh…...

考研数据结构——C语言实现插入排序

插入排序是一种简单直观的比较排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place(原地排序)&#…...

苍穹外卖学习笔记(十三)

三. 导入商品浏览功能代码 由于user的Controller与admin的相同,记得修改RestController注释 1. 查询分类 CategoryController package com.sky.controller.user;import com.sky.entity.Category; import com.sky.result.Result; import com.sky.service.Categor…...

​如果没有pos信息,只有一些近景的照片,可以用​编辑重建大师进行建模吗?​

可以。软件在新建工程时,提供有无人机和近景的选择,选择为近景即可。 重建大师,这是一款专为超大规模实景三维数据生产设计的集群并行处理软件,支持卫星影像、航空影像、倾斜影像和激光点云多源数据输入建模,可完成超…...

智能感知,主动防御:移动云态势感知为政企安全护航

数字化时代,网络安全已成为企业持续运营和发展的重要基石。随着业务扩展,企业资产的数量急剧增加,且分布日益分散,如何全面、准确地掌握和管理资产成为众多政企单位的难题。同时,传统安全手段又难以有效应对新型、隐蔽…...

论文笔记(四十六)RobotGPT: Robot Manipulation Learning From ChatGPT

xx RobotGPT: Robot Manipulation Learning From ChatGPT 文章概括摘要I. 介绍II. 相关工作III. 方法论A. ChatGPT 提示机器人操作B. 机器人学习 IV. 实验A. 衡量标准B. 实验设置C. 模拟实验D. 真实机器人实验E. AB测试 V. 结论 文章概括 引用: article{jin2024r…...

docker - 镜像操作(拉取、查看、删除)

文章目录 1、docker search --help(用于显示 Docker 搜索命令的帮助信息)2、docker pull(拉取镜像)3、docker images (查看镜像)3.1、docker images --help(用于显示 Docker 镜像管理相关命令的帮助信息)3.…...

如何选择数据库架构

选择合适的数据库架构是一个复杂的过程,它取决于多种因素,包括应用程序的需求、数据量的大小、并发访问量、数据一致性要求、预算以及技术团队的熟悉程度等。以下是一些关键的步骤和考虑因素,帮助你选择合适的数据库架构: 1. 分析…...

Mysql高级篇(中)——锁机制

锁机制 一、概述二、分类1、读锁2、写锁⭐、FOR SHARE / FOR UPDATE(1)NOWAIT(2)SKIP LOCKED(3)NOWAIT 和 SKIP LOCKED 的比较 ⭐、 脏写3、表级锁之 S锁 / X锁(1)总结(2…...

JavaWeb图书借阅系统

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 spring-mybatis.xml3.5 spring-mvc.xml3.5 login.jsp 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优…...

文档矫正算法:DocTr++

文档弯曲矫正(Document Image Rectification)的主要作用是在图像处理领域中,对由于拍摄、扫描或打印过程中产生的弯曲、扭曲文档进行校正,使其恢复为平整、易读的形态。 一. 论文和代码 论文地址:https://arxiv.org/…...

Qwen2.5-14B-Instruct+Pixel Script Temple:高校戏剧系AI辅助教学实战案例

Qwen2.5-14B-InstructPixel Script Temple:高校戏剧系AI辅助教学实战案例 1. 项目背景与价值 在高校戏剧教育领域,剧本创作一直是教学难点。传统教学模式下,学生需要花费大量时间在格式规范、基础场景构建等基础性工作上,而教师…...

Allegro PCB设计必备:3分钟搞定带钻孔数据的DXF文件导出(附常见错误排查)

Allegro PCB设计实战:高效导出带钻孔数据的DXF文件全攻略 在PCB设计领域,Allegro作为行业标杆工具,其文件输出质量直接关系到生产制造的准确性。特别是当设计需要与其他CAD系统协作或提交给PCB制造商时,DXF文件的完整性至关重要。…...

网络通信技术基础知识,网络通信技术数据包介绍

网络通信技术是关键技术之一,对于网络通信技术,我们应对其有所了解。为增加大家对网络通信技术的认识,本文将对网络通信技术的数据包结构和原理予以介绍。如果你对网络通信技术存在兴趣,不妨继续往下阅读哦。 在网络通信中, "…...

沉浸式翻译扩展常见问题解决方案

沉浸式翻译扩展常见问题解决方案 【免费下载链接】immersive-translate 沉浸式双语网页翻译扩展 , 支持输入框翻译, 鼠标悬停翻译, PDF, Epub, 字幕文件, TXT 文件翻译 - Immersive Dual Web Page Translation Extension 项目地址: https://gitcode.c…...

如何永久保存微信聊天记录:免费工具实现数据可视化与年度报告生成

如何永久保存微信聊天记录:免费工具实现数据可视化与年度报告生成 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trendi…...

LeagueAkari:英雄联盟智能辅助工具完全指南

LeagueAkari:英雄联盟智能辅助工具完全指南 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit LeagueAkari是一款基于英雄…...

深入S32K3XX以太网内部:用逻辑分析仪抓取MII时序,图解数据收发全过程

深入S32K3XX以太网内部:用逻辑分析仪抓取MII时序,图解数据收发全过程 在嵌入式系统开发中,以太网通信的底层实现往往像一个黑盒子——我们配置好寄存器,数据就神奇地传输了。但对于真正追求技术深度的开发者来说,理解信…...

bilibili-downloader开源工具:突破B站4K视频下载限制的全攻略

bilibili-downloader开源工具:突破B站4K视频下载限制的全攻略 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 在数字内容消…...

Wan2.1视频生成小白必看:避开这些坑,让你的视频生成一次成功

Wan2.1视频生成小白必看:避开这些坑,让你的视频生成一次成功 1. 为什么你的视频生成总是失败? 很多新手第一次使用Wan2.1视频生成模型时,都会遇到各种问题:生成的视频模糊不清、内容与描述不符、甚至直接失败。这通常…...

基于 SpringBoot 的自助图书借阅管理系统源码讲解

以下是一个基于 SpringBoot 的自助图书借阅管理系统的 核心源码讲解,涵盖用户管理、图书管理、借阅管理、设备对接等关键模块,代码结构清晰,可直接用于学习或二次开发。一、项目结构src/main/java/com/library/ ├── config/ # 配…...