MySQL进阶篇之SQL优化

news2024/10/7 19:27:59

03、SQL优化

3.1、插入数据

1、insert优化

  • 批量插入

    INSERT INTO 表名 (字段1,字段2,...) VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
    
    INSERT INTO 表名 VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
    
  • 手动提交事务

    start transaction;
    INSERT INTO 表名 (字段1,字段2,...) VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
    INSERT INTO 表名 (字段1,字段2,...) VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
    INSERT INTO 表名 (字段1,字段2,...) VALUES (值1,值2,...),(值1,值2,...),(值1,值2,...);
    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
    

    注意:主键顺序插入性能高于乱序插入

2、大批量插入数据

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。

在这里插入图片描述

通过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 表名 fields terminated by ',' lines terminated by '\n';

在这里插入图片描述

3.2、主键优化

1、数据组织方式

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

在这里插入图片描述

InnoDB的逻辑存储结构:

在这里插入图片描述

2、页分裂

页可以为空,也可以填充一半,也可以填充100%。每个页包含了2-N行数据(如果一行数据多大,会行溢出),根据主键排列。

  • 主键顺序插入

    在这里插入图片描述

  • 主键乱序插入

    主键乱序插入会出现页分裂现象:

    在这里插入图片描述

    这种现象称为页分裂

3、页合并

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

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

在这里插入图片描述

知识小贴士:

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

4、主键设计原则

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

3.3、order by 优化

1、MySQL的排序方式

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

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

2、举例:

① age、phone升序排序

# 没有创建索引时,根据age、phone进行排序
explain select id,age,phone from tb_user order by age, phone;

# 创建索引
create index idx_user_age_phone on tb_user(age,phone);

# 创建索引idx_user_age_phone后,根据age、phone进行升序排序
explain select id,age,phone from tb_user order by age, phone;

在这里插入图片描述

② age、phone降序排序

# 创建索引idx_user_age_phone后,根据age、phone进行降序排序
explain select id,age,phone from tb_user order by age desc, phone desc;

在这里插入图片描述

③ phone、age升序排序

# 创建索引idx_user_age_phone后,根据phone、age进行升序排序
explain select id,age,phone from tb_user order by phone, age;

在这里插入图片描述

注意:

在使用where时,where后的字段查询没有优先级,即where后面只要有索引最左列即可。

在使用order by时,order by后的字段排序有优先级,即order by后面的字段顺序需要按照索引列的顺序。

④ age升序排序、phone降序排序

# 创建索引idx_user_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);

# 创建索引idx_user_age_phone_ad后,根据age进行升序排序、phone进行降序排序
explain select id,age,phone from tb_user order by age asc,phone desc;

在这里插入图片描述

演示:

在这里插入图片描述

3、总结

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

  • 尽量使用覆盖索引。(避免使用select *)

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

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

    在这里插入图片描述

3.4、group by 优化

1、举例

① 根据profession字段分组

# 删掉目前的联合索引idx_user_profession_age_status
drop index idx_user_profession_age_status on tb_user;

# 执行分组操作,根据profession字段分组
explain select profession, count(*) from tb_user group by profession;

# 创建索引
create index idx_user_profession_age_status on tb_user(profession,age,status);

# 执行分组操作,根据profession字段分组
explain select profession, count(*) from tb_user group by profession;

在这里插入图片描述

② 使用最左前缀法则

# 执行分组操作,根据age字段分组
explain select age, count(*) from tb_user group by age;

# 执行分组操作,根据profession,age字段分组
explain select profession, age, count(*) from tb_user group by profession, age;

# 执行分组操作,当满足profession为“软件工程”的同时,根据age字段分组
explain select age,count(*) from tb_user where profession = '软件工程' group by age;

在这里插入图片描述

③ 根据age,profession字段分组

# 执行分组操作,根据age,profession字段分组
explain select profession,age,count(*) from tb_user group by age,profession;

在这里插入图片描述

group by后面的字段必须要按照所使用的索引列的顺序

2、总结

  • 在分组操作时,可以通过索引来提高效率。
  • 分组操作时,索引的使用也是满足最左前缀法则的。

3.5、limit优化

一个常见又非常头疼的问题就是limit 2000000,10,此时需要MySQL排序前20000010记录,仅仅返回2000000-2000010的记录,其他记录丢弃,查询排序的代价非常大。

优化思路:一般分页查询时,通过创建覆盖索引能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。

在这里插入图片描述

3.6、count优化

1、简介

explain select count(*) from tb_user;

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高;

InnoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

优化思路:自己计数。

2、count的几种用法

  • count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是NULL,累计值就加1,否则不加,最后返回累计值。

  • 用法:

    • count(*):一行行的判断此行数据是否为null,如果不为null,累计值加1;如果为null,则不加,最终返回累计值。

      InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

    • count(主键):一行行的判断id对应的数据是否为null,如果不为null,累计值加1;如果为null,则不加,最终返回累计值。

      InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)。

    • count(字段):一行行的判断此字段对应的数据是否为null,如果不为null,累计值加1;如果为null,则不加,最终返回累计值。

      • 没有not null约束:InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。
      • not null约束:InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。
    • count(1):对于查询到的数据,每行记录都用1代替,然后在服务层对1进行累加。

      InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。

    性能count(字段)<count(主键)<count(1)≈count(*)

    在这里插入图片描述

3.7、update优化

1、演示行级锁:

在这里插入图片描述

2、演示表锁:

在这里插入图片描述

解决方案:给name字段建立索引

create index idx_course_name on course(name);

3、InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁,从而导致并发性能降低。

注意:尽量根据主键/索引字段进行数据更新。

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

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

相关文章

【SQL 审核查询平台】Archery使用介绍

Archery 读作&#xff1a;[ˈɑːrtʃəri] Archery目录界面截图功能清单依赖清单框架前端组件服务端部署准备运行配置启动访问修改配置项基础设置添加实例添加资源组资源组关联用户/实例添加权限组用户关联权限组/权限设置工单上线和查询的审批流程设置默认资源组和默认权限组…

数组的几种常见方法及其返回值

push()&#xff1a;向数组的末尾添加一个或多个元素&#xff1b;返回的是数组的新长度。unshift()&#xff1a;向数组的开头添加一个或多个元素&#xff1b;返回的是数组的新长度。shift()&#xff1a;删除数组的第一个元素&#xff0c;并返回被删除的&#xff08;即第一个元素…

品牌社交营销链路 | 小红书数据分析网站

【导语】 2022年&#xff0c;小红书品牌推广竞争愈演愈烈&#xff0c;从小红书用户画像分析&#xff0c;到抢占小红书关键词排名&#xff0c;营销动作内卷升级&#xff0c;那么在2023的新篇章&#xff0c;如何打通社交种草的链路呢&#xff1f; 1、运营企业账号&#xff0c;建立…

MQTT 代理助力ECARX实现汽车智能互联

一、应用背景 ECARX是中国汽车制造商吉利旗下的一家科技创新企业&#xff0c;致力于持续打造行业领先的智能网联生态开放平台&#xff0c;全面为车企赋能&#xff0c;创造更智能、更安全的出行体验&#xff0c;为智能互联汽车提供智能解决方案。 ECARX主要业务包括吉利汽车的…

让Apache Beam在GCP Cloud Dataflow上跑起来

简介 在文章《Apache Beam入门及Java SDK开发初体验》中大概讲了Apapche Beam的简单概念和本地运行&#xff0c;本文将讲解如何把代码运行在GCP Cloud Dataflow上。 本地运行 通过maven命令来创建项目&#xff1a; mvn archetype:generate \-DarchetypeGroupIdorg.apache.b…

Swift 新 async/await 同步机制小技巧:消除“多余”的 await 关键字

概览 在使用多个Actor 共同实现同步功能的时候&#xff0c;我们往往会看到如下使用场景&#xff1a; Actor A 必须在主线程上运行&#xff0c;Actor B可以在任意线程上运行&#xff0c;但需要适时的调用 Actor A 中的方法。 在这种情况下&#xff0c;我们会遇到如下代码&#…

从移动激光扫描数据中自动提取单棵树的双重生长方法

论文题目&#xff1a;A dual growing method for the automatic extraction of individual trees from mobile laser scanning data Abstract 在城市场景的杂乱点云中&#xff0c;街道树木与其他物体交织在一起&#xff0c;阻碍了对单个树木的自动提取。根据树木的一般构成&a…

React:安装配置使用scss

目录 前言&#xff1a; 1.暴露隐藏的webpack配置&#xff1b; 2.安装sass的相关包&#xff1b; 3.项目中新建一些scss文件&#xff1b; 4.在config文件夹中找到webpack.config.js文件&#xff0c;进行配置&#xff1b; 5.测试使用&#xff1b; 前言&#xff1a; 项目采用…

Python之Pandas的常用技能【写入数据】

1、背景&#xff1a; 最近在工作中遇到越来越多的的使用pandas或者python来处里写入操作&#xff0c;尤其是对excel文件或者csv文件的操作更是常见&#xff0c;这里将写入操作总结如下&#xff0c;方便记忆&#xff0c;也分享给大家&#xff0c;希望对阅读者能够有所帮助 2、…

nvdiffrec:Extracting Triangular 3D Models, Materials, and Lighting From Images

论文主页 https://nvlabs.github.io/nvdiffrec/git主页 https://github.com/NVlabs/nvdiffrec新闻报道 https://redian.news/wxnews/36324YuQiao0303 读后感 https://blog.csdn.net/qq_34342853/article/details/125622816b站演示效果视频 https://www.bilibili.com/video/BV1P…

8天获offer|祝贺信息技术老师获CSC资助赴意大利访学

I老师拟申报CSC青年骨干教师项目&#xff0c;指定欧洲学校&#xff0c;且要求半个月内获得邀请函。我们8天就取得了意大利帕多瓦大学的offer&#xff0c;研究方向完全相符&#xff0c;因而顺利通过了CSC审批。后经繁琐的手续&#xff0c;I老师最终获得签证&#xff0c;如期出国…

ABB机器人设置有效载荷的2种方法具体步骤(直接输入法+自动识别推算法2)

ABB机器人设置有效载荷的2种方法具体步骤(直接输入法+自动识别推算法2) 为什么要设置有效载荷Loaddata? 对于搬运应用的机器人只有设定正确的工具和载荷数据,机器人才能正确的工作; 对于搬运比较重的产品,或工具的重量也比较重,需要设置工具及搬运对象的重心和重量; …

2023年黑马Java入门到精通教程--程序流程控制

程序流程控制 程序执行的几种常见形式 分支结构 If分支 根据判定的结果&#xff08;真或假&#xff09;决定执行某个分支的代码 If分支的作用 If分支有三种格式 switch分支 也是匹配条件去执行分支, 适合做值匹配的分支选择&#xff0c;结构清晰&#xff0c;格式良好 swit…

通信原理笔记—基带信号的检测与最佳接收

目录 在加性白高斯噪声信道条件下数字基带信号的接收&#xff1a; 加性高斯白噪声干扰下的信号检测&#xff1a; 最大似然判决准则&#xff1a;误码率最小意义上的最佳判决&#xff1a; 先验等概及最佳判决时的误码率计算&#xff1a; 高斯噪声干扰下二进制信号的检测&…

Mock.js(简单代替后台)

Mock.js &#xff08;官网http://mockjs.com/&#xff09;是一款模拟数据生成器&#xff0c;旨在帮助前端开发人员独立于后端进行开发&#xff0c;帮助编写单元测试。二、为什么使用mockjs在做开发时&#xff0c;当后端的接口还未完成&#xff0c;前端为了不影响工作效率&#…

【实际开发12】- Utils / tools

目录 1. 自定义工具类 概念 / 解析 1. 构建方式 1. XxxClassl 类 public xxx() → new XxxClass() 2. XxxClassl 类 public static xxx() → XxxClass.xxx() 2. Interface 1. public interface XxxMapper → private final XxxMapper 2. public interface IXxxService →…

面经八,笔试加面试

Java 开发面试题&#xff0c;尧壁信科有限公司 笔试&#xff1a; 1、Java 中有几种类型的流&#xff1f; 字节流字符流&#xff0c;输入流输出流 2、什么是 java反射? 在程序的运行状态中&#xff0c;对于任意一个类&#xff0c;都可以知道整这个类的所有属性和方法&#xf…

如何锁定Excel表格的公式不被修改

很多小伙伴在制作Excel表格的时候&#xff0c;往往还会设置很多公式&#xff0c;但如果不小心或被他人随意修改了公式&#xff0c;就会造成数据错误&#xff0c;为了避免这种情况&#xff0c;其实我们可以设置保护&#xff0c;让公式锁定无法被修改。 下面举一个例子来看看如何…

【C语言 数据结构】串

文章目录串类型的定义串的表示和实现定长顺序存储堆分配存储表示串的块链存储表示串的模式匹配算法字串的定位函数匹配模式的改进算法串类型的定义 对于由多个字符&#xff08;≥ 0&#xff09;组成的字符串&#xff08;例如 http://data.biancheng.net&#xff09;&#xff0…

Git版本如何使用命令进行升级(win10)

1、桌面鼠标右键&#xff0c;点击Git Bash Here,输入git --version 查看目前Git版本。 2、输入git update-git-for-windows 升级版本&#xff0c;再输入y同意升级并覆盖之前的版本。 我在版本升级的过程中遇到了error: RPC failed&#xff1b; curl 92 HTTP/2 stream 0 was not…