SQL优化详解

news2024/12/23 15:43:42

目录

·插入数据

insert的优化(少量数据)

批量插入

手动事务提交

主键顺序插入

插入大量数据

·主键优化

数据组织方式:

页分裂:

主键顺序插入的方式:

主键乱序插入:

页合并:

主键设计原则:

·order by优化

·group by 优化

·limit优化

优化方式:

·count优化

count的用法:

几种用法的优劣:

count(主键)

count(字段)

count ( 1 )

count (* )

·update优化


·插入数据

插入多条数据的优化方案:(插入一条没啥优化的哈)

insert的优化(少量数据)

批量插入

像这种模式,一般建议数据量最多在500-1000条左右。

Insert into tb_test values(1,'To'),(2,'WO'),(3,'jee');

手动事务提交

因为每句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;

主键顺序插入

一般而言主键顺序插入还是乱序插入都可以,建议主键顺序插入

乱序:2 5 22 86 34 8987 213

顺序:1 2 3 4 5 6 7 8 9

插入大量数据

一次性插入大量数据,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';

插入1000000的数据需要16s,如果是使用insert大概需要十几分钟。

·主键优化

数据组织方式:

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

为什么都是根据主键顺序存放的呢:

数据库的数据是根据表空间,段,区,页,行的形式存放的,行就是每一条数据,表是InnoDB管理的最小单位。数据的索引分为聚集索引和二级索引,聚集索引使用的是B+树,它的每个主键都会在树的最下面存放,而前面的向上分裂的部分作为查询数据的索引。所以表的数据都是根据主键顺序组织存放的。

页分裂:

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

主键顺序插入的方式:

就从前往后插数据,第一个页写满了,就写入第二个页,然后用一个双向指针维护两个页的关系。

主键乱序插入:

如果是这种情况,第一个页写满了,但是要插入一个id为50的数据,这个时候怎么办呢?

他会新建一个数据页,然后把第一个页分一半出来,把50插入到新的数据页中

然后把链表指针改变一下,把1号的下一个改为3号,3号的next改为2号。

所以:顺序插入的效率最高。

页合并:

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

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

主键设计原则:

1、满足业务需求的情况下,尽量降低主键的长度

因为二级索引的最下面存放都是主键,主键太长,就会占用大量的IO和磁盘。

2、插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。

3、尽量不要使用UUID做主键或者是其他自然主键,如身份证号。

两个原因:无序且过长

4、业务操作时,避免对主键的修改。

·order by优化

在mysql中有两种排序方式

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

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

所以优化的就需要让排序方式尽量变成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,phgne);
#创建索引后,根据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 ;

创建了联合

·group by 优化

分组操作的研究中,我们主要研究索引对分组操作的影响。

这是没有索引的查询效率:

下面

是创建索引后的性能:

建立适当的索引,满足最左前缀法则即可提高分组效率。

如果查询时是这样,pro在where,而age在group by也是满足最左前缀法则的。

·limit优化

什么时候要考虑limit进行优化呢:

select * from sb_tu limit 0,10;

第0条数据开始,查10个数据

select * from sb_tu limit 100000,10;

从第100000个数据开始查10个数据。

越往后查询的代价越大,他会把0到100000个数据全部排序,然后丢弃,只返回100000到100010这10个数据。

优化方式:

覆盖索引加子查询

1:先查出想要的id

select id from tb_sku order by id limit 100000,10;

2:表联查查数据

select s.* from tb_sku s , (select id from tb_sku order by id limit 100000,10) a where s.id = a.id;

原方法耗时19s,优化后耗时11.47s。

·count优化

select count(*) from tb_sku;

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高。如果有where条件就需要一行一行的读取了。

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

目前由于存储引擎的缘故,没有太好的优化count的方法,常用的就是使用像redis之类的数据库进行自我计数。

count的用法:

count(*),count(主键),count(字段),count(1);

count(主键)统计有多少个主键。一般为数据库表的总数。

count(字段)是查询该字段不为空的总数,如果为空则不计入。count(*)同理。

count(1)是给每个字段添加一个1的标识,然后统计1的数量。

几种用法的优劣:

count(主键)

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

count(字段)

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

count ( 1 )

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

count (* )

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

按照效率排序的话,count(字段)<count(主键id)<count(1) = count(*),所以尽量使用count(*)。

·update优化

我们在更新数据时一定要根据id进行更新,因为在事务中使用id索引进行update用的是行级锁,该行在事务未commit之前不会再被其他人修改。

如果使用字段进行字段进行查询则会被开启表级锁,整张表在该事务未提交之前不会再被修改,会影响其他人操作。

如果字段有建立索引表则不会被添加表级锁,而是行级锁。

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

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

相关文章

软件技术主要学什么课程

软件技术专业主要学习的课程和内容有编程语言、数据结构与算法、数据库技术等&#xff0c;以下是上大学网( www.sdaxue.com)整理的软件技术主要学什么课程&#xff0c;供大家参考&#xff01; 编程语言&#xff1a;掌握一种或多种编程语言&#xff0c;如C#、Java、Python、C等&…

EdgeOne 免费证书快速实现网站 HTTPS 访问

在当今互联网环境下&#xff0c;HTTPS访问已经成为现代网站的必备功能。HTTPS 访问不仅能够更有效地保障用户在访问到网站时的数据安全传输&#xff0c;防止信息泄露、消息劫持等问题&#xff0c;在搜索引擎中&#xff0c;未实现 HTTPS 还会被浏览器提示为不安全网站&#xff0…

Windows平台PyCharm之PySide6开发环境搭建与配置

PySide6 是一个用于创建跨平台 GUI 应用程序的库&#xff0c;它是 Qt for Python 的官方库。Qt 是一个跨平台的 C 应用程序框架&#xff0c;用于开发具有图形用户界面&#xff08;GUI&#xff09;的应用程序。PySide6 允许开发者使用 Python 语言访问 Qt 的功能&#xff0c;从而…

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2 1、 Flyer[0].step() Flyer[1].step() Dev.step(4)2、 for i in range(2):Flyer[i].step()Dev.step(2)Dev.turnLeft() Flyer[0].step(2) Dev.step(2)3、 for i in range(2):Flyer[i * 2 1].step()Dev.step(-i - 2)Dev.tu…

OpenAI 发布 AI 生成图片检测器;Meta 推出 AI 广告创意工具;Google 正式发布 Pixel 8a,主打 AI

OpenAI 发布 AI 生成图片检测器 OpenAI 昨日官宣推出专用的 AI 监测工具&#xff0c;用于监测图片是否由其旗下 AI 图片生成工具 DALL-E 生成&#xff0c;准确率高达 98.8%。 不过该公司表示&#xff0c;这个检测工具并非旨在检测 Midjourney 和 Stability 等其他流行生成器生…

QAnything 在mac M2 上纯python环境安装使用体验(避坑指南)

这是一篇mac m2本地纯python环境安装 qanything的文章。安装并不顺利&#xff0c;官方提供的模型无法在本地跑。 这篇文章记录了&#xff0c;使用xinference来部署本地模型&#xff0c;并利用openAi的通用接口的方式&#xff0c;可以正常使用。 记录了遇到的所有的问题&#xf…

使用Docker安装Nginx

一、Nginx介绍 Nginx 是一款高性能的开源 Web 服务器和反向代理服务器&#xff0c;具有高效能、高稳定性、低资源消耗等优点。可以处理大量并发请求&#xff0c;支持多种协议&#xff0c;还能实现负载均衡、缓存等功能&#xff0c;在互联网应用中被广泛使用。在Nginx中&#xf…

ICode国际青少年编程竞赛- Python-2级训练场-迷宫

ICode国际青少年编程竞赛- Python-2级训练场-迷宫 1、 Dev.step(3) Dev.turnLeft() for i in range(2):Dev.step(4)Dev.turnRight() for i in range(2):Dev.step(2)Dev.turnLeft() Dev.step(3) Dev.step(-9)2、 Dev.step(3) Dev.turnRight() Dev.step(2) Dev.turnLeft() for i …

AI视频教程下载:给企业管理层和商业精英的ChatGpt课程

课程内容大纲&#xff1a; 1-引言 2-面向初学者的生成性人工智能 3-与ChatGPT一起学习提示101 详细介绍了如何使用ChatGPT的六种沟通模式&#xff0c;并提供了各种实际应用场景和示例&#xff1a; **Q&A模式&#xff08;问题与答案模式&#xff09;**&#xff1a; - 这…

区块链 | NFT 水印:Review on Watermarking Techniques(三)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证&#xff0c;即通过使用 R S A \mathsf{RSA} RSA…

96、技巧-只出现一次的数字

思路 首先不考虑额外空间的话使用一个set去重即可。第二种就是异或运算。 异或操作的性质 身份元素&#xff1a;任何数与0进行异或运算&#xff0c;结果仍然是原数&#xff0c;即 x ^ 0 x。自反性&#xff1a;任何数与自身进行异或运算&#xff0c;结果是0&#xff0c;即 x…

Spring Cloud Consul 4.1.1

该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法&#xff0c;为 Spring Boot 应用程序提供 Consul 集成。通过一些简单的注释&#xff0c;您可以快速启用和配置应用程序内的常见模式&#xff0c;并使用基于 Consul 的组件构建大型分布式系统。提供的模式…

Python版Spark core详解

文章目录 第一章 SparkCore1.1. Spark环境部署1.1.1. Spark介绍1.1.1.1. 什么是Spark1.1.1.2. Spark与MapReduce的对比框架对比运行流程对比 1.1.1.3. Spark的组件1.1.1.4. Spark的特点 1.1.2. Spark的安装部署1.1.2.1. Spark安装包下载1.1.2.2. Spark部署模式介绍1.1.2.3. Loc…

解决Vue devtools插件数据变化不会自动刷新

我们使用devtools插件在监测vuex中表单或自定义组件的数据&#xff0c;发现页面数据发生变化后&#xff0c;但是devtools中还是老数据&#xff0c;必须手动点击devtools刷新才能拿到最新的数据。很烦&#xff01; 解决方案&#xff1a; 打开chrome的设置&#xff0c;向下翻&…

docker自建GitLab仓库

摘要 GitLab 是一个功能强大的开源代码托管平台&#xff0c;它不仅提供了代码存储和版本控制的核心功能&#xff0c;还集成了项目管理、CI/CD 流水线、代码审查等企业级特性。本文将指导你如何在自己的服务器上搭建 GitLab 社区版&#xff0c;创建一个完全属于自己的开源仓库&…

##10 卷积神经网络(CNN):深度学习的视觉之眼

文章目录 前言1. CNN的诞生与发展2. CNN的核心概念3. 在PyTorch中构建CNN4. CNN的训练过程5. 应用:使用CNN进行图像分类5. 应用:使用CNN进行时序数据预测代码实例7. 总结与展望前言 在深度学习的领域中,卷积神经网络(CNN)已经成为视觉识别任务的核心技术。自从AlexNet在2…

引入RabbitMQ

前置条件 docker 安装 mq docker run \-e RABBITMQ_DEFAULT_USERdudu \-e RABBITMQ_DEFAULT_PASS123456 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network hmall \-d \rabbitmq:3.8-management可能会出现&#xff1a;docker: Er…

FPGA+炬力ARM实现VR视频播放器方案

FPGA炬力ARM方案&#xff0c;单个视频源信号&#xff0c;同时驱动两个LCD屏显示&#xff0c;实现3D 沉浸式播放 客户应用&#xff1a;VR视频播放器 主要功能&#xff1a; 1.支持多种格式视频文件播放 2.支持2D/3D 效果实时切换播放 3.支持TF卡/U盘文件播放 4.支持定制化配置…

【机器学习300问】79、Mini-Batch梯度下降法的原理是什么?

Mini-Batch梯度下降法是一种将训练数据集分成小批次进行学习的优化方法&#xff0c;通过这种方式&#xff0c;可以有效地解决内存限制问题并加速学习过程。 一、为什么要使用Mini-Batch&#xff1f; 在机器学习尤其是深度学习中&#xff0c;我们常常面临海量数据处理的问题。如…

内网穿透速度慢

内网穿透速度慢原因及优化策略 在计算机网络应用中&#xff0c;内网穿透是一个常见的需求&#xff0c;它允许外部网络访问位于内部网络&#xff08;如企业局域网或家庭网络&#xff09;中的设备或服务。然而&#xff0c;有时用户在进行内网穿透时会遇到速度慢的问题&#xff0…