mysql基础4sql优化

SQL优化

插入数据优化
如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化。
insert into tb_test values(1,'tom');
insert into tb_test values(2,'cat');
insert into tb_test values(3,'jerry');--  优化方案一:批量插入数据
Insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');-- 优化方案二:手动控制事务
start transaction;
insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
insert into tb_test values(4,'Tom'),(5,'Cat'),(6,'Jerry');
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
大批量插入数据

如果一次性需要插入大批量数据(比如: 几百万的记录),使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。操作如下:

-- 客户端连接服务端时,加上参数 -–local-infile  加载本地数据
mysql –-local-infile -u root -p-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
select @@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' ;

主键优化

在上一小节,我们提到,主键顺序插入的性能是要高于乱序插入的。 这一小节,就来介绍一下具体的原因,然后再分析一下主键又该如何设计。
1). 数据组织方式
在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。行数据,都是存储在聚集索引的叶子节点上的。

在InnoDB引擎中,数据行是记录在逻辑结构 page 页中的,而每一个页的大小是固定的,默认16K。那也就意味着, 一个页中所存储的行也是有限的,如果插入的数据行row在该页存储不小,将会存储到下一个页中,页与页之间会通过指针连接。

2). 页分裂

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

A. 主键顺序插入效果
①. 从磁盘中申请页, 主键顺序插入
②. 第一个页没有满,继续往第一页插入
③. 当第一个也写满之后,再写入第二个页,页与页之间会通过指针连接
④. 当第二页写满了,再往第三页写入B. 主键乱序插入效果
涉及移动数据到新页,重新设置链表指针。

3). 页合并

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

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

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

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

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

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

对于以上的两种排序方式,Using index的性能高,而Using filesort的性能低,我们在优化排序操作时,尽量要优化为 Using index

drop index idx_user_phone on tb_user;
drop index idx_user_phone_name on tb_user;
drop index idx_user_name on tb_user;-- Extra  以下两个查询均为 Using filesort
explain select id,age,phone from tb_user order by age ;
explain select id,age,phone from tb_user order by age, phone ;-- 创建age,phone的索引
create index idx_user_age_phone_aa on tb_user(age,phone);
explain select id,age,phone from tb_user order by age;	-- Extra:Using index 
explain select id,age,phone from tb_user order by age , phone;	-- Extra:Using index-- 根据age, phone进行降序排序
-- Extra:Backward index scan;Using index  
-- Backward index scan,这个代表反向扫描索引,在MySQL8版本中,支持降序索引,我们也可以创建降序索引
explain select id,age,phone from tb_user order by age desc , phone desc ; -- 根据phone,age进行升序排序,phone在前,age在后。 排序时,也需要满足最左前缀法则,否则也会出现 filesort。 
-- Extra:Using index; Using filesort   违背最左前缀,索引失效,创建的age,phone索引
explain select id,age,phone from tb_user order by phone , age;-- 根据age, phone进行降序一个升序,一个降序
-- 因为创建索引时,如果未指定顺序,默认都是按照升序排序的,而查询时,一个升序,一个降序,此时就会出现Using filesort。
explain select id,age,phone from tb_user order by age asc , phone desc ;

创建联合索引(age 升序排序,phone 倒序排序)

-- 创建联合索引(age 升序排序,phone 倒序排序)
create index idx_user_age_phone_ad on tb_user(age asc ,phone desc);
explain select id,age,phone from tb_user order by age asc , phone desc ;	-- Extra:Using index

由上述的测试,我们得出order by优化原则:
A. 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
B. 尽量使用覆盖索引。
C. 多字段排序, 一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)。
D. 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k)。

group by优化

分组操作,我们主要来看看索引对于分组操作的影响。

drop index idx_user_pro_age_sta on tb_user;
drop index idx_email_5 on tb_user;
drop index idx_user_age_phone_aa on tb_user;
drop index idx_user_age_phone_ad on tb_user;

pdf 55 blbl 91-34

出现 Using temporary时,使用到临时表 性能较低
--  Extra:Using temporary; Using filesort   
explain select profession,count(*) from tb_user  group by profession;-- 对于 profession , age, status 创建一个联合索引
create index idx_user_pro_age_sta on tb_user(profession , age , status);
-- Extra:  Using index 
explain select profession,count(*) from tb_user  group by profession;-- 单独查age  不满足最左前缀法则
-- Extra:Using index; Using temporary; Using filesort   性能不高explain select age,count(*) from tb_user  group by age;-- 联合查profession,age
-- Extra:  Using index
explain select profession,age,count(*) from tb_user  group by profession,age;-- 添加where条件,提高效率
-- Extra: Using where; Using index
explain select age,count(*) from tb_user where profession = '软件工程' group by age;

所以,在分组操作中,我们需要通过以下两点进行优化,以提升性能:

A. 在分组操作时,可以通过索引来提高效率。

B. 分组操作时,索引的使用也是满足最左前缀法则的。

limit优化

在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。

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

select * from tb_sku limit 10;   -- 10 rows in set (0.00 sec)   很快 
select * from tb_sku limit 5000000,10; -- 10 rows in set (42.42 sec)  很慢-- 优化查询
select id from tb_sku order by id limit 5000000,10;  -- 10 rows in set (18.69 sec)
--  将上面的结果看成临时表,优化后-- 10 rows in set (17.09 sec)
select * from tb_sku t , (select id from tb_sku order by id limit 5000000,10) a where t.id = a.id;
count优化

3.6.1 概述

MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高; 但是如果是带条件的count,MyISAM也慢。
InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

主要的优化思路:自己计数(可以借助于redis这样的数据库进行,但是如果是带条件的count又比较麻烦了)。

count用法

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

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

-- 尽量使用count(*)
按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(*)
count(主键):InnoDB 引擎会遍历整张表,把每一行的 主键id 值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)count(字段):没有not null 约束 : InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。有not null 约束:InnoDB 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。count(数字):InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。count(*):InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。
update优化

我们主要需要注意一下update语句执行时的注意事项。

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

-- 如下:执行删除的SQL语句时,会锁定id为1这一行的数据,然后事务提交之后,行锁释放。
begin;
update course set name = 'javaEE' where id = 1 ;
--  新的终端开启事务执行,执行是OK的
begin;
update course set name = 'javaEE' where id = 2 ;-- name无索引  行锁升级为了表锁。 导致该update语句的性能大大降低
update course set name = 'SpringBoot' where name = 'PHP' ;
-- create index idx_coruse_name on course(name);  创建索引后再执行不会锁表。

视图

视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

4.1.2 语法
1). 创建
CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
-- 创建视图
create or replace view stu_v_1 as select id,name from student where id <= 10;2). 查询
查看创建视图语句:SHOW CREATE VIEW 视图名称;
查看视图数据:SELECT * FROM 视图名称 ...... ;
show create view stu_v_1;
select * from stu_v_1;
select * from stu_v_1 where id < 3;3). 修改
方式一:CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
方式二:ALTER VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
create or replace view stu_v_1 as select id,name,no from student where id <= 10;
alter view stu_v_1 as select id,name from student where id <= 10;4). 删除
DROP VIEW [IF EXISTS] 视图名称 [,视图名称] ...
drop view if exists stu_v_1;-- 插入数据
insert into stu_v_1 values(6,'Tom');	-- 插入后可以查询到
insert into stu_v_1 values(17,'Tom22');  -- 查不到数据,创建视图时的条件为 id<=10

4.1.3 检查选项
使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,不符合执行失败。
MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项: CASCADED (默认,级联检查依赖的视图)和 LOCAL(本地检查)。

4.1.4 视图的更新
要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一
项,则该视图不可更新:

A. 聚合函数或窗口函数(SUM()、 MIN()、 MAX()、 COUNT()等)
B. DISTINCT
C. GROUP BY
D. HAVING
E. UNION 或者 UNION ALL

1

create view stu_v_count as select count(*) from student;
insert into stu_v_count values(10);    --插入失败

视图作用

1). 简单
视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
2). 安全
数据库可以授权,但不能授权到数据库特定行和特定的列上。通过视图,用户只能查询和修改他们所能见到的数据,从而将敏感的字段隔离开。
3). 数据独立
视图可帮助用户屏蔽真实表结构变化带来的影响。

-- 案例
1). 为了保证数据库表的安全性,开发人员在操作tb_user表时,只能看到的用户的基本字段,屏蔽手机号和邮箱两个字段。create view tb_user_view as select id,name,profession,age,gender,status,createtime from tb_user;select * from tb_user_view;2). 查询每个学生所选修的课程(三张表联查),这个功能在很多的业务中都有使用到,为了简化操
作,定义一个视图。
create view tb_stu_course_view as select s.name student_name , s.no student_no ,c.name course_name from student s, student_course sc , course c where s.id =sc.studentid and sc.courseid = c.id;select * from tb_stu_course_view;

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

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

相关文章

生骨肉冻干真的对猫身体好吗?排行榜靠前对猫身体好的生骨肉冻干推荐

随着科学养猫知识的广泛传播&#xff0c;生骨肉冻干喂养正逐渐受到养猫人士的青睐。生骨肉冻干真的对猫身体好吗&#xff1f;生骨肉冻干不仅符合猫咪的饮食天性&#xff0c;还能提供全面均衡的营养&#xff0c;有助于维护猫咪的口腔和消化系统健康。然而&#xff0c;许多猫主人…

Open CASCADE学习|最小二乘法拟合直线

最小二乘法&#xff0c;又称最小平方法&#xff0c;起源于十八世纪的大航海探索时期&#xff0c;发展于天文领域和航海领域。其历史可以追溯到法国科学家马里勒让德于1805年首次提出这一概念&#xff0c;而1809年&#xff0c;高斯在他的著作《天体运动论》中也提出了最小二乘法…

JavaScript中三目运算

三目运算符是JavaScript中常用的一种条件语句&#xff0c;也称为条件运算符。它由问号&#xff08;?&#xff09;和冒号&#xff08;:&#xff09;组成&#xff0c;用于根据条件的真假返回不同的值。在本篇文章中&#xff0c;我将详细介绍三目运算符的语法、用法和实例&#x…

自学新标日第八课 未完结

第八课 单词 因为总是电脑打字 手写不会 以后单词都先自己手写了 晚更&#xff01;&#xff01; 单词假名声调词义プレゼント2礼物チケット&#xff11;门票パンフレット&#xff11;小册子記念品きねんひん&#xff10;纪念品スケジュールひょうすけじゅーるひょう&#xf…

xilinx FPGA 除法器ip核(divider)的学习和仿真(Vivado)

在设计中&#xff0c;经常出现除法运算&#xff0c;实现方法&#xff1a; 1、移位操作 2、取模取余 3、调用除法器IP核 4、查找表 简单学习除法器IP。 网上很多IP翻译文档&#xff0c;不详细介绍&#xff0c;记录几个重要的点&#xff1a; 1、三种算法模式(不同模式所消耗的资…

【Linux 进程概念】

【Linux 进程概念】 冯诺依曼体系结构冯诺依曼结构简要解释&#xff1a;你用QQ和朋友聊天时数据的流动过程 操作系统(OperatorSystem)概念设计OS的目的定位操作系统的上下层都分别是什么如何理解“管理"总结 进程基本概念描述进程-PCBtask_ struct内容 组织进程查看进程通…

大模型围剿战:Kimi如何在免费与盈利之间找到平衡?

文 | 大力财经 在近期的互联网科技领域&#xff0c;一款名为Kimi的国产大型AI模型引起了广泛关注。随着Kimi的火爆&#xff0c;国内的大型科技公司纷纷开始关注并投入到长文本处理技术的竞争中。 阿里巴巴、360等知名企业纷纷宣布了他们的长文本处理能力&#xff0c;分别达到…

网络——套接字编程UDP

目录 端口号 源端口号和目的端口号 认识TCP协议和UDP协议 网络字节序 socket编程接口 socket常见接口 sockaddr结构 UDP socket bind recvfrom sendto 编写客户端 绑定INADDR_ANY 实现聊天功能 端口号 在这之前我们已经说过源IP地址和目的IP地址&#xff0c;还有…

微信小程序的页面制作---常用组件及其属性2

一、标签栏taBar 在全局配置文件app.json中添加taBar配置&#xff0c;可实现标签栏配置。标签栏最少2个&#xff0c;最多5个 &#xff08;1&#xff09;如何配置标签栏&#xff1f; 1》先建多个文件&#xff0c;&#xff08;以我的index&#xff0c;list&#xff0c;myform文…

最近很火的游戏,人渣/SCUM(更新V0.9.517.81845)

包含DLC • SCUM Deluxe • SCUM Deluxe 2 • SCUM Danny Trejo • SCUM Hair Deluxe 1 • SCUM Luis Moncada • SCUM Charms 1 • SCUM Weapon Skins 1 中文设置 OPTIONS-LANGUAGE-中文(简体) 特别提示 • 通过“\SCUM\Binaries\Win64\SCUM.exe”启动游戏 • 如果…

Microsoft Excel 快捷键 (keyboard shortcut - hotkey)

Microsoft Excel 快捷键 [keyboard shortcut - hotkey] References 表格内部换行快捷键 Alt Enter 快速将光标移到表末 Ctrl End 快速将光标移到表首 Ctrl Home References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

人工智能(Educoder)-- 搜索技术 -- 盲目式搜索

第1关&#xff1a;盲目搜索之宽度优先搜索算法 任务描述 本关任务&#xff1a;给定迷宫地图以及在迷宫中的起始位置&#xff0c;利用宽度优先搜索算法求解走出迷宫的最短路径长度&#xff0c;走出迷宫意味着达到迷宫地图的边界&#xff08;所有位置下标0开始&#xff09;。 …

Dockerfile, nginx.conf文件解读

Dockerfile文件 FROM registry.tongdun.me/library/alpine3-nginx:1.0 ENV APPNAMEedith-frontendADD nginx.conf /etc/nginx/ ADD ok.htm /home/admin/ RUN mkdir /home/admin/dist COPY /dist/ /home/admin/dist/ RUN mkdir /home/admin/nginx RUN mkdir /home/admin/nginx/…

水电站泄洪预警广播系统方案

一、行业背景 近年来由于危险河道管理措施不到位&#xff0c;调峰电站泄水风险长期存在&#xff0c;信息通报制度缺失以及民众安全警觉性不高等因素导致的水电站在泄洪时冲走下游河道游客以及人民财产的事故频发。 我司通过物联网、云计算、大数据、人工智能等技术手段&#x…

【电脑装机】笔记本开机启动快捷键汇总

联想 Lenovo 和 ThinkPad 笔记本&#xff1a; 启动项界面快捷键&#xff1a;F12 或者 F2 进 BIOS 快捷键&#xff1a;F2 或者 FnF2 戴尔 Dell 笔记本&#xff1a; 启动项界面快捷键&#xff1a;F12 进 BIOS 快捷键&#xff1a;F2 或者 FnF2 惠普 HP 笔记本&#xff1a; 启…

不能从所选图层建立3d模型--模大狮模型网

在Revit中&#xff0c;从所选图层直接创建3D模型并不是一个常规的操作方式。通常情况下&#xff0c;你需要手动创建文字或者图形&#xff0c;然后将其转换为3D模型。 如果你有一个平面上的文字或图形&#xff0c;想要将其转换为3D模型&#xff0c;你可以使用以下步骤&#xff1…

什么是虚拟线程?

1、典型回答 Java 中的虚拟线程&#xff0c;也叫做协程或“轻量级线程”&#xff0c;它诞生于JDK 19(预览 API)&#xff0c;正式发布于 JDK 21&#xff0c;它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程&#xff0c;不直接和操作系统的物理线程一一对应&#xff0c;因此它可…

文献速递:基于SAM的医学图像分割---SAM-Med2D

Title 题目 SAM-Med2D 01 文献速递介绍 医学图像分割在通过识别和勾画各种组织、器官或感兴趣区域来分析医学图像中发挥着至关重要的作用。准确的分割可以帮助医生精确识别和定位病理区域&#xff0c;从而实现更准确的诊断和治疗。此外&#xff0c;对医学图像进行定量和定性…

Node.js之沙盒专题

​ Node.js一直是薄弱项&#xff0c;今天特意整理一下&#xff0c;基本上是各个大佬写的大杂烩&#xff0c;仅用于学习记录~~~ 1. child_process 首先介绍一下nodejs中用来执行系统命令的模块child_process。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物…

简化业务流程,AppLink连接一定签

APPlink是什么 APPlink是RestCloud打造的一款简单易用的零代码自动化集成平台&#xff0c;为业务流程提供自动化的解决方案&#xff0c;将企业内部的核心系统以及第三方应用程序和云服务等进行集成。无论是开发人员还是业务人员&#xff0c;都可以使用APPlink轻松构建出高效、…