SQL优化——插入数据、主键优化、order by 优化、group by 优化、limit 优化、count优化、update优化、

目录

1、SQL优化1——插入数据(Insert)

1.1、普通插入:

1.1.1、采用批量插入(一次插入的数据不建议超过1000条)

1.1.2、手动提交事务

1.1.3、主键顺序插入

1.2、大批量插入

1.2.1、在客户端连接服务器的时候,不用mysql -u root -p,加上参数--local-infile(这一行在bash/cmd界面输入)

1.2.2、设置全局函数local_infile=1,也就是开启从本地加载文件导入数据的开关

1.2.3、查看开关是否开启

1.2.4、执行load指令将准备好的数据,加载到表结构中

2、SQL优化2——主键优化

2.1、页分裂

2.1.1、主键顺序插入:会根据主键的ID顺序进行插入,第一页写完之后,开始第二页,之间会维护一个双向指针

2.1.2、主键乱序插入:主键ID不是排序好的, 当我们要插入ID=50的时候,因为叶子节点是有序的,所以50必须存放在47之后,也就是应该将50放在第一页。

2.2、页合并

2.3、主键索引设计原则

2.3.1、满足业务条件的情况下,尽量减小主键的长度,因为耳机索引的时候叶子节点挂的是主键

2.3.2、插入数据的时候,尽量选择顺序插入,可以选择自增主键

2.3.3、尽量不要使用无序,长度太长的作为主键,例如身份证

2.3.4、在实际操作的时候,尽量避免对主键的操作

3、SQL优化3——order by 优化

3.1、using filesort

3.2、using index

3.3、举个例子

3.3.1、创建表格

3.3.2、执行以下两个查询语句。

3.3.3、但是当name升序,phone降序,又会出现什么情况呢

4、SQL优化4——group by 优化

4.1、从表中查找gender,并对gender进行分组

4.2、此时可以给这个字段添加索引,提高效率

4.3、执行语句

4.4、总结:

4.4.1、在分组操作时,可以通过索引来提高效率

4.4.2、分组操作的时候,还是必须要满足最左前缀法则的 

5、SQL优化5——limit 优化

5.1、优化方案

5.1.1、通过创建覆盖索引能够比较好的提高性能

5.1.2、之后,通过覆盖索引加子查询形式进行优化

5.2、实施例子

5.2.1、查询9000000-9000010

5.2.2、使用覆盖索引加快速度,直接通过主键索引进行排序和查询,先执行order by再执行limit

5.2.3、通过id找数据

5.3、总结

6、SQL优化6——count优化

6.1、count的几种用法

6.1.1、如果count函数的参数(count里面写的字段)不是null(字段值不是null),累计就加一,最后返回累计值

6.1.2、用法:count(*)、count(主键)、count(字段)、count(1)

6.1.3、count(*)和count(主键)一样,因为主键不可以为空;count(字段)只计算字段值不是null的行;count(1)引擎会为每一行添加一个1,然后count这个1,返回结果也跟count(*)一样;count(null)返回0

6.2、count用法的性能

6.2.1、count(主键):InnoDB引擎会遍历整张表,把每行的主键id都取出来,返回给服务层,服务层拿到主键之后,直接按照行进行累加(主键不可能为空)

6.2.2、count(字段):没有not null约束的话,InnoDB引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,服务层会判断是否为null,不为null,计数累加。如果有not null约束的话,InnoDB引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,直接按行进行累加

6.2.3、count(1):InnoDB引擎会遍历整张表,但不取值,服务层对于返回的每一层,放一个数字1进去,直接按行进行累加

6.2.4、count(*):InnoDB引擎并不会把全部字段都取出来,而是专门做了优化,不取值,服务层直接按行进行累加;

6.3、总结效率

7、SQL优化7——update优化

7.1、这句sql语句id有主键索引,索引只会锁这一行

7.2、这句话name没有索引,所以会将整张表都锁住进行数据更新(当我们开了两个事务的时候,必须等这句话的事务完成之后,才能提交另一个事务)


1、SQL优化1——插入数据(Insert)

在SQL优化中,如何高效插入数据也是比较重要的一点,那么现有的插入数据类型主要分为普通插入和大批量插入。

1.1、普通插入:

1.1.1、采用批量插入(一次插入的数据不建议超过1000条)

语法:

Insert into tb_test values(1,'A'),(2,'B'),(3,'C')...;

1.1.2、手动提交事务

这比起1.1的优点就是1.1在没插入一次数据就要提交一次,而手动提交事务是所有的数据插入完成之后,一起进行提交,相比较于1.1更高效,更省时间

语法:

Start transaction;
Insert into tb_test values(1,'A'),(2,'B'),(3,'C')...;
Insert into tb_test values(4,'D'),(5,'E'),(6,'F')...;
Insert into tb_test values(7,'G'),(8,'H'),(9,'I')...;
......
commit;

1.1.3、主键顺序插入

举个例子:

乱序插入:4,7,2,5,78,9,1;

顺序插入:1,2,5,4,7,9,78;

顺序插入的性能会比乱序插入的性能更高

1.2、大批量插入

如果一次性需要插入大量的数据(上百万的数据100w-500w),使用insert插入的话就很低效,性能较低,此时可以使用MySQL数据库提供的load指令插入

语法:

1.2.1、在客户端连接服务器的时候,不用mysql -u root -p,加上参数--local-infile(这一行在bash/cmd界面输入)

mysql --local-infile -u root -p

1.2.2、设置全局函数local_infile=1,也就是开启从本地加载文件导入数据的开关

set global local_infile=1;

1.2.3、查看开关是否开启

select @@local_infile;

1.2.4、执行load指令将准备好的数据,加载到表结构中

load data local infile '/你的sql文件地址' into table 'tb_user' fields terminated by ',' lines terminated by '\n';

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

2、SQL优化2——主键优化

2.1、页分裂

主键索引的页可以为空,也可以为一半,也可以为100%,每个页都会包含2N行数据(如果一行的数据过大,超出了一定的阈值之后,会出现行溢出)

2.1.1、主键顺序插入:会根据主键的ID顺序进行插入,第一页写完之后,开始第二页,之间会维护一个双向指针

2.1.2、主键乱序插入:主键ID不是排序好的, 当我们要插入ID=50的时候,因为叶子节点是有序的,所以50必须存放在47之后,也就是应该将50放在第一页。

但是第一页现在剩下的空间不够ID=50,那么此时就会开辟新的数据页,找到第一个数据页50%的数据,将23和47这两个数据移动到第三页,再将50放在47后面

此时双向链表第一页就把不能接上第二页了,而是指向第三页。这种现象就叫页分裂

2.2、页合并

当删除一行记录的时候,实际上记录并没有被物理删除,只是标记一下(例如红色圆圈里面的13,14,15,16),并且这四个空间变得运行被其他记录声明使用。当页中删除的记(MERGE_THRESHOLD)页的50%的时候,InnoDB会寻找最靠近的前后页,看看是否可以将两个页合并,从而优化空间。

也就是说,当13,14,15,16被标记删除后,系统会找到第三页的17,18,19.将这三个数据放在第二页,那么第三页就空出来了,这样就可以达到优化空间的效果

 MERGE_THRESHOLD:可以自己设计

2.3、主键索引设计原则

2.3.1、满足业务条件的情况下,尽量减小主键的长度,因为耳机索引的时候叶子节点挂的是主键

2.3.2、插入数据的时候,尽量选择顺序插入,可以选择自增主键

2.3.3、尽量不要使用无序,长度太长的作为主键,例如身份证

2.3.4、在实际操作的时候,尽量避免对主键的操作

3、SQL优化3——order by 优化

 关于SQL优化,order by 在执行过程中会出现两种类型:using index 和 using filesort

3.1、using filesort

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

3.2、using index

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

3.3、举个例子

3.3.1、创建表格

索引为:

3.3.2、执行以下两个查询语句。

explain select id, age, phone from tb_user order by age;
explain select id, age, phone from tb_user order by age,phone;

发现Extra都是using filesort,查询效率不高,解决办法就是

create index index_age_phone on tb_user(age,phone);

 发现现在的都是using index,查询效率提高

3.3.3、但是当name升序,phone降序,又会出现什么情况呢

explain select id, age, phone from tb_user order by age asc,phone desc;

发现既有using index又有using filesort。因为age升序之后,phone需要反向排序

解决办法就是,建立索引

create index index_age_phone_ad on tb_user(age asc,phone desc);

4、SQL优化4——group by 优化

 在SQL优化的时候,group by分组操作的时候,可以通过索引来提高效率

举个例子

4.1、从表中查找gender,并对gender进行分组

 explain select gender, count(*) from tb_user group by gender;

发现Extra=using temporary,表示效率不高。

4.2、此时可以给这个字段添加索引,提高效率

 create index index_user_gender_age_phone on tb_user(gender,age,phone);

4.3、执行语句

explain select age, count(*) from tb_user group by age;

出现这个原因是因为,他违背了最左前缀法则

解决:

 explain select gender, age, count(*) from tb_user group by gender, age;

或者

explain select  age, count(*) from tb_user where gender='1' group by age;

4.4、总结:

4.4.1、在分组操作时,可以通过索引来提高效率

4.4.2、分组操作的时候,还是必须要满足最左前缀法则的 

5、SQL优化5——limit 优化

 如果数据量很小的时候,limit优化效果是很不明显的,当数据量很大的时候(上百万),需要分页查询数据的时候,例如limit 2000000,10,此时需要MySQL排序前2000000条记录,但是我们仅仅需要得到的数据量只有2000000-2000010,这10个记录,其他的记录丢弃,这样会造成排序的代价非常大。那么,该如何优化呢?

5.1、优化方案

5.1.1、通过创建覆盖索引能够比较好的提高性能

5.1.2、之后,通过覆盖索引加子查询形式进行优化

5.2、实施例子

5.2.1、查询9000000-9000010

select * from tb_user limit 9000000,10;

这个语句将会耗时很长,如何解决呢?

5.2.2、使用覆盖索引加快速度,直接通过主键索引进行排序和查询,先执行order by再执行limit

select id from tb_user order by id limit 9000000,10;

这个语句就得到了9000000-9000010这10个数据的id

5.2.3、通过id找数据

错误示范:MySQL不支持in里面使用limit

select * from tb_user where id in (select id from tb_user order by id limit 9000000,10);

正确动作:将select * from tb_user where id in (select id from tb_user order by id limit 9000000,10);的结果看成一张表

select t.* from tb_user as t, (select id from tb_user order by id limit 9000000,10) as a where t.id=a.id;

5.3、总结

limit优化包括两个步骤:先覆盖索引,再子查询。

6、SQL优化6——count优化

关于count优化,首先我们先来看一下引擎。

MyISAM引擎:把一个表的总行数存在了磁盘上,因此执行coount(*)的时候会直接返回这个数,效率很高(前提是不适用where);

InnoDB引擎:在执行count(*)的时候,需要把数据一行一行的从引擎中读出来,然后累计技术。那么InnoDB引擎是现有的最常用的引擎,该如何进行优化呢?可以自己去维护,自己计数,写入一个数据,就加一;

6.1、count的几种用法

6.1.1、如果count函数的参数(count里面写的字段)不是null(字段值不是null),累计就加一,最后返回累计值

6.1.2、用法:count(*)、count(主键)、count(字段)、count(1)

6.1.3、count(*)和count(主键)一样,因为主键不可以为空;count(字段)只计算字段值不是null的行;count(1)引擎会为每一行添加一个1,然后count这个1,返回结果也跟count(*)一样;count(null)返回0

6.2、count用法的性能

6.2.1、count(主键):InnoDB引擎会遍历整张表,把每行的主键id都取出来,返回给服务层,服务层拿到主键之后,直接按照行进行累加(主键不可能为空)

6.2.2、count(字段):没有not null约束的话,InnoDB引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,服务层会判断是否为null,不为null,计数累加。如果有not null约束的话,InnoDB引擎会遍历整张表,把每一行的字段值都取出来,返回给服务层,直接按行进行累加

6.2.3、count(1):InnoDB引擎会遍历整张表但不取值,服务层对于返回的每一层,放一个数字1进去,直接按行进行累加

6.2.4、count(*):InnoDB引擎并不会把全部字段都取出来,而是专门做了优化,不取值,服务层直接按行进行累加;

6.3、总结效率

count(字段)<count(主键)<count(1)<count(*),索引尽量使用count(*)。

7、SQL优化7——update优化

 在update优化的时候,尽量避免行锁升级为表锁

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁

7.1、这句sql语句id有主键索引,索引只会锁这一行

update tb_user set number='123' where id=1;

7.2、这句话name没有索引,所以会将整张表都锁住进行数据更新(当我们开了两个事务的时候,必须等这句话的事务完成之后,才能提交另一个事务)

update tb_user set number='123' where name='test';

那么如果改进呢?就是给name字段创建索引

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python——桌面摄像头软件(附源码+打包)

目录 一、前言 二、桌面摄像头软件 2.1、下载项目 2.2、功能介绍 三、打包工具&#xff08;nuitka&#xff09; 四、项目文件复制&#xff08;我全部合到一个文件里面了&#xff09; 五、结语 一、前言 看见b站的向军大叔用electron制作了一个桌面摄像头软件 但是&#x…

【离散化】【 树状树状 】100246 将元素分配到两个数组中

本文涉及知识点 离散化 树状树状 LeetCode 100246 将元素分配到两个数组中 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount &#xff0c;使得 greaterCount(arr, val) 返回数组 arr 中 严格大于 val 的元素数量。 你需要使用 n 次操作&#x…

Network LSA 结构简述

Network LSA主要用于描述一个区域内的网络拓扑结构&#xff0c;包括网络中的路由器和连接到这些路由器的网络。它记录了每个路由器的邻居关系、连接状态以及连接的度量值&#xff08;如带宽、延迟等&#xff09;&#xff0c;以便计算最短路径和构建路由表。display ospf lsdb n…

CentOS下安装Kafka3

kafka是分布式消息队列&#xff0c;本文讲述其在centos&#xff08;centos 7.5&#xff09;下的安装。安装过程可以参考其官方文档https://kafka.apache.org/36/documentation.html 首先在官网 https://kafka.apache.org/downloads 下载Kafka二进制文件&#xff08;官网的压缩包…

WordPress免费的远程图片本地化下载插件nicen-localize-image

nicen-localize-image&#xff08;可在wordpress插件市场搜索下载&#xff09;&#xff0c;是一款用于本地化文章外部图片的插件&#xff0c;支持如下功能&#xff1a; 文章发布前通过编辑器插件本地化 文章手动发布时自动本地化 文章定时发布时自动本地化 针对已发布的文章…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于条件风险价值的虚拟电厂参与能量及备用市场的双层随机优化》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 这篇文章的标题涉及到以下几个关键点…

数字革命的浪潮:Web3如何改变一切

随着数字技术的不断发展&#xff0c;人类社会正迎来一场前所未有的数字革命浪潮。在这个浪潮中&#xff0c;Web3技术以其去中心化、安全、透明的特性&#xff0c;正在逐渐改变着我们的生活方式、商业模式以及社会结构。本文将深入探讨Web3技术如何改变一切&#xff0c;以及其所…

【学习心得】请求参数加密的原理与逆向思路

一、什么是请求参数加密&#xff1f; 请求参数加密是JS逆向反爬手段中的一种。它是指客户端&#xff08;浏览器&#xff09;执行JS代码&#xff0c;生成相应的加密参数。并带着加密后的参数请求服务器&#xff0c;得到正常的数据。 常见的被加密的请求参数sign 它的原理和过程图…

【C语言】【洛谷】P1125笨小猴

一、个人解答 #include<stdio.h> #include<string.h>int prime(int num);int main() {char max a, min z;int maxn0, minn1000;char str[100];int num[26] { 0 };fgets(str, sizeof(str), stdin);str[strcspn(str, "\n")] \0;for (int i 0; str[i]…

ABAP - SALV 教程15 用户点击按钮交互功能

SALV增加了按钮&#xff0c;那么该怎么实现点击了按钮实现交互功能呢&#xff1f;可以通过注册事件并且在对应的method中写入相关逻辑&#xff0c;来实现点击按钮后的逻辑。通过自定义状态栏的方式添加按钮&#xff1a;http://t.csdnimg.cn/lMF16通过使用派生类的方式添加按钮&…

【MetaGPT】配置教程

MetaGPT配置教程&#xff08;使用智谱AI的GLM-4&#xff09; 文章目录 MetaGPT配置教程&#xff08;使用智谱AI的GLM-4&#xff09;零、为什么要学MetaGPT一、配置环境二、克隆代码仓库三、设置智谱AI配置四、 示例demo&#xff08;狼羊对决&#xff09;五、参考链接 零、为什么…

java学习(常用类)

一、包装类&#xff08;针对八种基本数据类型相应的引用类型--包装类. 1)包装类和基本数据类型的相互转换 装箱&#xff1a;基本类型->包装类型 拆箱&#xff1a;包装类型->基本类型 //以下是int类型和char类型演示。 public class temp1 {public static void main(St…

【Web - 框架 - Vue】随笔 - 通过CDN的方式使用VUE 2.0和Element UI

通过CDN的方式使用VUE 2.0和Element UI - 快速上手 VUE 网址 https://cdn.bootcdn.net/ajax/libs/vue/2.7.16/vue.js源码 https://download.csdn.net/download/HIGK_365/88815507测试 代码 <!DOCTYPE html> <html lang"en"> <head><meta …

C语言基础(五)——结构体与C++引用

七、结构体与C引用 7.1 结构体的定义、初始化、结构体数组 C 语言提供结构体来管理不同类型的数据组合。通过将不同类型的数据组合成一个整体&#xff0c;方便引用 例如&#xff0c;一名学生有学号、姓 名、性别、年龄、地址等属性&#xff0c;如果针对学生的学号、姓名、年龄…

VMware 虚拟机安装windows 10操作系统

先提前准备好镜像文件 1.创建新的虚拟机 2.选择自定义&#xff0c;然后下一步 v Windows 建议选择2G以上&#xff0c;下一步 选择网络地址转换&#xff08;NAT&#xff09;&#xff0c;下一步 这里可按自己的需求来分区&#xff0c;也可以安装好后再分区 选择立即重启&#xff…

【计算机毕业设计】208基于SSM的在线教育网站

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Redis高并发高可用详解

Redis高并发高可用 复制 在分布式系统中为了解决单点问题&#xff0c;通常会把数据复制多个副本部署到其他机器&#xff0c;满足故障恢复和负载均衡等需求。Redis也是如此&#xff0c;它为我们提供了复制功能&#xff0c;实现了相同数据的多个Redis 副本。复制功能是高可用Re…

Effective objective-c-- 内存管理

Effective objective-c-- 内存管理 前言理解引用计数引用计数工作原理属性存取方法中的内存管理自动释放池保留环要点 以ARC简化引用计数使用ARC时必须遵循的方法和命名规则变量的内存管理语义ARC如何清理实例变量覆写内存管理方法要点 在dealloc方法中只释放引用并解除监听要点…

【数据分享】2000~2022年中国区域MOD16A2GF V061 潜在蒸散发PET数据

各位同学们好&#xff0c;今天和大伙儿分享的是2000~2022年中国区域MOD16A2GF V061 潜在蒸散发PET数据。如果大家有下载处理数据等方面的问题&#xff0c;您可以私信或者评论。 Running, S., Mu, Q., Zhao, M., Moreno, A. (2021). MODIS/Terra Net Evapotranspiration Gap-Fil…

[JavaWeb玩耍日记]HTML+CSS+JS快速使用

目录 一.标签 二.指定css 三.css选择器 四.超链接 五.视频与排版 六.布局测试 七.布局居中 八.表格 九.表单 十.表单项 十一.JS引入与输出 十二.JS变量&#xff0c;循环&#xff0c;函数 十三.Array与字符串方法 十四.自定义对象与JSON 十五.BOM对象 十六.获取…