SQL优化详解

目录

·插入数据

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.mfbz.cn/a/607218.html

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

相关文章

HTML5/CSS3粒子效果进度条 超炫酷进度条动画源码

特效介绍 之前我已经分享了几款效果很不错的CSS3进度条插件&#xff0c;比如CSS3 Loading进度条加载动画特效、CSS3 3D进度条按钮 18款精美样式。今天我再来分享一款很有特色的HTML5/CSS3进度条应用。这款进度条插件在播放进度过程中出现粒子效果&#xff0c;就像一些小颗粒从…

二本生如何从大一准备考研!?保姆级全攻略

如果是二本大学&#xff0c;那考研确实是一个很好的机会 如果大家就有考研的打算&#xff0c;那就好好学习&#xff0c;好好学习英语&#xff0c;数学&#xff08;理工科&#xff09;和专业课&#xff0c;这些课程在考研的时候是肯定会考的 特别是英语和数学&#xff08;理工…

每日Attention学习5——Multi-Scale Channel Attention Module

模块出处 [link] [code] [WACV 21] Attentional Feature Fusion 模块名称 Multi-Scale Channel Attention Module (MS-CAM) 模块作用 通道注意力 模块结构 模块代码 import torch import torch.nn as nnclass MS_CAM(nn.Module):def __init__(self, channels64, r4):super(…

五一开始内卷前端,如何迅速的一个月内找到工作!

写在前面 五一过了代表新的一年不知不觉过了半年了&#xff0c;各位工作找到怎么样&#xff0c;有没有在工作中遇到解决不了的问题&#xff0c;这些问题后面怎么处理了呢&#xff1f; hello大家好&#xff0c;我又又又来了&#xff0c;今天纯干货&#xff0c;上班的朋友适当摸…

【SAP ME 39】SAP ME WebService超时时间设置

禁止废话&#xff0c;直接上图&#xff01;&#xff01;&#xff01; SAP技术官方说明

Dark Reader:夜间模式,启动!

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、介绍二、下载安装1、Chrome应用商店&#xff08;需科学&#xff09;2、第三方直链下载 三、使…

深入探索数据链路层:网络通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在网络通信的宏伟世界中&#xff0c;数据链路层扮演着至关重要的角色。它位于物理层和网络层之间&#xff0c;不仅直接…

HuggingFace烧钱做了一大批实验,揭示多模态大模型哪些trick真正有效

构建多模态大模型时有很多有效的trick&#xff0c;如采用交叉注意力机制融合图像信息到语言模型中&#xff0c;或直接将图像隐藏状态序列与文本嵌入序列结合输入至语言模型。 但是这些trick为什么有效&#xff0c;其计算效率如何&#xff0c;往往解释得很粗略或者或者缺乏充分…

C++ Builder XE EnumWindowsProc遍历所有窗口的名称

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { // 这里可以添加你的处理逻辑 // 例如&#xff0c;将句柄添加到列表中或者其他操作 // 这里我们仅仅输出到调试窗口 OutputDebugString(L"枚举窗口句柄: "); char windowHandle[10];…

ROS 2边学边练(45)-- 构建一个能动的机器人模型

前言 在上篇中我们搭建了一个机器人模型(其由各个关节&#xff08;joint&#xff09;和连杆&#xff08;link&#xff09;组成)&#xff0c;此篇我们会通过设置关节类型来实现机器人的活动。 在ROS中&#xff0c;关节一般有无限旋转&#xff08;continuous&#xff09;,有限旋转…

【每日力扣】98. 验证二叉搜索树 与 108. 将有序数组转换为二叉搜索树

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&a…

【优选算法】——双指针——15. 三数之和

目录 1.题目 2.解法&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 3.代码实现 1.题目 15. 三数之和 提示 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足…

【LLM第三篇】名词解释:RLHF——chatgpt的功臣

RLHF (Reinforcement Learning from Human Feedback) &#xff0c;直译为&#xff1a;“来自人类反馈的强化学习”。RLHF是一种结合了强化学习和人类反馈的机器学习方法&#xff0c;主要用于训练大模型以执行复杂的任务&#xff0c;尤其是当这些任务难以通过传统的奖励函数来精…

重学java 33.API 4.日期相关类

任何事&#xff0c;必作于细&#xff0c;也必成于实 —— 24.5.9 一、Date日期类 1.Date类的介绍 1.概述: 表示特定的瞬间,精确到亳秒 2.常识: a.1000毫秒 1秒 b.时间原点:1970年1月1日 0时0分0秒(UNIX系统起始时间),叫做格林威治时间,在0时区上 c.时区:北京位于东八区,一个时区…

Linux 操作系统线程1

目录 一、线程 1.1线程的基本概念 1.2 线程相关的API函数 1.2.1 线程的创建 1.2.2 线程退出 1.2.3 线程等待函数 1.2.4 获取线程ID 1.2.5 线程取消 1.2.6 线程的清理函数 一、线程 1.1线程的基本概念 线程是属于进程&#xff1b;一个进程可以有多个线程&#xff…

salmon使用体验

文章目录 salmon转录本定量brief模式一&#xff1a;fastq作为输入文件需要特别注意得地方 模式二&#xff1a; bam文件作为输入 salmon转录本定量 brief 第一点是&#xff0c;通常说的转录组分析其中有一项是转录本定量&#xff0c;这是一个很trick的说话&#xff0c;说成定量…

深度学习——前馈全连接神经网络(鸢尾花)

前馈全连接神经网络对鸢尾花数据集进行分类 1.导入所需要的包2.打印训练集和测试集二维数组3.定义模型4.打印模型信息5.权重和偏执6.编译网络和训练网络7.打印二维数据表格8.绘制图像9.查看准确率 1.鸢尾花数据集可以用 from sklearn.datasets import load_iris 方式获取&#…

医院预约挂号|基于Springboot+vue的医院预约挂号系统小程序的设计与实现(源码+数据库+文档)

医院预约挂号系统小程序 目录 基于Springboot&#xff0b;vue的医院预约挂号系统小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1小程序端 后台功能模块 4.2.1管理员功能 4.2.2医生功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

jsp 实验16 MVC 表白墙

源代码以及执行结果截图&#xff1a; ExpressWish_Bean.java package web; import java.util.HashMap; import java.util.ArrayList; import java.util.Iterator; public class ExpressWish_Bean { public HashMap<String,ExpressWish> wishList; ArrayList&…

#内部类#

1,概念 如果一个类定义在另一个类的内部&#xff0c;这个内部类就叫做内部类。内部类是一个独立的类&#xff0c;它不属于外 部类&#xff0c;更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。重点&#xff1a;内部类是一个独立的类 注意&…