MySQL进阶 - SQL优化

news2024/11/25 0:36:40

01 插入数据

【一】insert优化:

   ① 不要一行一行插入数据,直接批量插入多行数据(但一个insert语句不要插入超过一千条)。

         insert into 表名 (字段列表) values (xx,xx...),(xx,xx...)...;

   ② 在进行插入操作时手动提交事务,避免频繁的开启提交事务。

         start transaction;

         insert into 表名 (字段列表) values (xx,xx...),(xx,xx...)...;

         insert into 表名 (字段列表) values (xx,xx...),(xx,xx...)...;

         insert into 表名 (字段列表) values (xx,xx...),(xx,xx...)...;

         commit;

    ③ 按照主键顺序插入,因为按照主键顺序的性能比乱序插入的性能高。

【二】大批量的数据插入:

    ① 说明:大批量的数据插入,使用insert语句的性能较低,此时得使用load指令进行插入。

                   通过load指令可以一次性将本地文件中的数据全部加载进数据库表结构中。

    ② 使用load指定要做的三步操作:

         a. 客户端连接服务器时,加上参数 --local-infile

             mysql --local-infile -u root -p

         b.  查看MySQL从本地加载文件导入数据的开关

              select @@local_infile;---》1为开启,0为关闭

             

         b.  设置全局参数local_infile为1,开启MySQL从本地加载文件导入数据的开关

              set global local_infile = 1;

            

         c. 建立一个表,等会用于存放大批量数据

         d. 上传本地含有大批量数据的文件,到linux服务器中,上传后一些相关查看操作如下图所示:

           

            e. 使用load指令大批量添加数据到数据库表结构中:

                load data local infile '含有大批量数据的文件路径' into table 表名 fields terminated by ‘字段分隔符’ lines terminated by '换行符';

                记法:记载数据本地文件 哪个文件 给哪个表 场地的分隔符是什么 行的换行符是什么

     ③  使用load指令插入数据时,最好也是按照主键顺序插入,因为这样性能高。

02 主键优化

【说明】:逐渐优化主要讨论按照主键顺序插入的性能为什么比乱序插入的高。

【一】InnoDB存储引擎中数据组织方式

           InnoDB存储引擎中,表数据都是根据主键顺序组织存放的( 因为InnoDB存储引擎根据索引的存储结构将索引又分为聚集索引和二级索引,聚集索引每个叶子节点下存储的是每一行数据,有主键索引的表,聚集索引由主键索引构成)。

【二】InnoDB的逻辑存储结构

    ① 页是InnoDB存储引擎磁盘管理的最小单元,一个页的大小为16k

    ② 一个区的大小为1M,可以包含64个页

【三】往数据库表结构中插入数据的底层原理

    ① 主键顺序插入:一个页满了之后,再使用下一个页

    ② 主键乱序插入:

         a. 为了保证索引的有序性,在乱序插入时通常会发生 页分裂 现象

         b. 页分裂:如下图所示,50只能插入到47的后面,但page1已经满的,此时会将page1一半的数据移动到page3中,

                           然后将50插入到47之后,并修改page1,2,3的链表走向。

           c. 补充:页合并现象:当删除一行记录时,实际上并不会进行物理删除,只是会把它标记成删除状态,一旦被标记成删除状态,表示这块空间允许被其他记录声明使用。当某一页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最近的页(前或后),看看是否可以将两个页合并以优化空间的使用。

【四】主键的设计原则

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

         (原因:在一张数据库表结构中,主键索引和聚集索引只能有一个,而二级索引可以有很多个,二级索引的叶子节点下存储的就是对应的主键,如果主键索引较长,二级索引较多,会占用大量的磁盘空间,在查询的时候也会耗费大量的磁盘IO)

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

    ③ 尽量不要使用UUID(和rand类似,可生成随机数)做主键或者其他的自然主键,例如:身份证号,因为无序就会发生页分裂,而且长度较长,会消耗大量的磁盘IO。

03 order by优化

【一】:MySQL中的排序方式

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

    ② Using index:通过通过索引直接返回排序结果,不需要额外排序,性能比Using filesort要高,优化order by时尽量让排序方式为Using index。

    ③ 补充:在建立索引时,如果不指定字段的排序方式,默认是升序排列

         指定语法:create index 索引名 on 表名 (字段名1 asc, 字段名2 desc ...);

         解释:create index idex_user_age_pho_ad on tb_user (age asc, phone desc);表示创建一个联合索引,索引按age升序排序,在age相同的情况下按phone降序排序

【二】:判断某条select语句的排序,到底使用的那种排序方式 :

   ① 一个字段,无索引,filesort

   ② 一个字段,有索引,覆盖索引,index

   ③ 一个字段,有索引,非覆盖索引,filesort

   ④ 多个字段,都无索引,filesort

   ⑤ 多个字段,都有索引,但并不构成联合索引,filesort

   ⑥ 多个字段,都有索引,构成联合索引,但不符合最左前缀法则,覆盖索引,index,filesort

   ⑦ 多个字段,都有索引,构成联合索引,但不符合最左前缀法则,非覆盖索引,filesort 

        --》因为要select联合索引中没有的字段,不能在直接走联合索引拿数据再去排序了。

   ⑧ 多个字段,都有索引,构成联合索引,字段都是同升序/降序,覆盖索引,index

   ⑨ 多个字段,都有索引,构成联合索引,字段存在有升序,降序的,index,filesort

        (可以建立新的联合索引,把filesort优化掉,但也必须要满足覆盖索引)

   ⑩ 多个字段,都有索引,构成联合索引,非覆盖索引,filesort

【关于底层的一些说明】

   ① 磁盘文件中可以是存储着数据库表中一行一行的数据,磁盘文件中也可以是存放着索引的数据结构和指向数据库表每一行数据的指针,当我们去使用索引查找数据时,实际上最终也是会根据地址找对应的数据,相当于多了一次磁盘io。

   ② 聚集索引虽然存储着数据库表中的数据,但MySQL是不会主动使用聚集索引去拿每一行的数据的,除非你主动使用了聚集索引,例如:order by id等,拿数据库表中的信息一般是在对应的磁盘文件中进行全表扫描拿到。

   ③ 如果order by后面的字段没有索引,则会对数据库表结构进行全表扫描,拿到每一行的数据,然后在排序缓冲区中进行相关的排序,此种排序方式属于filesort。

   ④ 多个字段,都有索引,构成联合索引,字段都是同升序/降序,覆盖索引,为什么排序方式是index?答:由于order by后面排序的字段有联合索引,且字段都是同升序/降序(这种情况与创建索引时字段的顺序是一致或相反的,相反可以反向扫描)且符合覆盖索引 (此时select查找排序后的内容都包含在联合索引中),因此我们可以直接通过走联合索引拿到最终的排序结果,所以排序方式是index。 

   ⑤ 多个字段,都有索引,构成联合索引,字段都是同升序/降序,不满足覆盖索引,为什么排序方式是filesort?答:因为走联合索引只能拿到联合索引中存在字段的排序结果,如果select查询时还要查询联合索引中并不存在的字段,则此时我们需要对数据库表结构进行全表扫描,拿到每一行的数据,然后在排序缓冲区中再进行相关的排序,所以排序的方式是filesort。

   ⑥ 多个字段,都有索引,构成联合索引,但不符合最左前缀法则,覆盖索引,为什么排序方式是index,filesort?因为虽然我们不能直接使用联合索引去拿到最终的排序结果,但我们可以利用该联合索引拿到每一行的数据,然后再在排序缓冲区中进行排序,毕竟B+树中有现成的数据且字段都是我们想要的,和去磁盘中拿,当然是走联合索引去拿数据更好,所以排序的方式是index,filesort。

   ⑦ 多个字段,都有索引,构成联合索引,字段存在有升序,降序的,为什么排序方式是index,filesort?同上⑥。

【三】order by 优化:

    ① 根据order by后面的字段建立合适的索引,多字段排序时,也遵循最左前缀法则

    ② 查询排序后的结果时,尽量使用覆盖索引,否则又会走Using filesort

    ③ 多字段,一个升序,一个降序等类似字段排序规则不统一的情况,我们可以在创建相关的联合索引时指定字段的排序方式

    ④  如果不可避免出现了filesort那就使用它吧,在大数据排序时,我们可以适当增大排序缓冲区大小sort_buffer_size,因为如果排序缓冲区放不下,会在磁盘文件中进行排序,这样相对在排序缓冲区排序效率较低

          a. 查看排序缓冲区的大小:select variables like 'sort_buffer_size';--> buffer缓冲

          b. 修改排序缓冲区的大小:set global sort_buffer_size = xxx;

04 group by优化

【一】分析不同情况下,使用的分组方式:

    ① 根据group by后面的字段进行分组操作时,如果group by后面的字段没有索引则会进行全表扫描拿到表中的数据后在临时表中按照相关字段进行分组处理。

    ② 如果group by后面的字段有索引 (一个字段/联合索引满足最左前缀法则),覆盖索引,由于索引底层其实相当于分好组了,所以直接走索引就可以拿到分组的结果。

    ③ 如果group by后面的字段有索引 (联合索引不满足最左前缀法则),覆盖索引,此时会通过走索引拿到数据,然后再将数据拿到临时表中按照相关字段进行分组处理,因此分组的方式为index, Using temporary(使用临时表)

    ④ 注意:使用where进行条件筛选后,再使用group by对不满足最左前缀法则字段分组,的效果等同于满足最左前缀法则的效果

           例如:where pro group by age == group by pro, age

【二】group by优化:

    ① 给group by后面的字段建立适当的索引,通过走索引直接拿的性能比走全表扫描再在临时表中分组效率要高很多。

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

05 limit优化

【一】现象:对于limit来说,大数据量的情况下进行分页查询,起始索引越大所需时间越长,效率越低。

【二】limit优化:

   ① 如果主键是连续的可以先使用where过滤掉前面的数据,然后再使用 limit 进行分页查询 

       例如:select id,name form user where id > 1000000 limit 10;

   ② 如果主键不是连续的,可以使用覆盖索引+子查询的方式:先对主键进行排序,然后limit,并使用覆盖索引拿到待查询数据的主键;然后利用子查询,查询到待查数据的每一行。

       例如:select id from tb_sku order by id limit 500000,10;

                  select * from tb_sku where id in (select id from tb_sku order by id limit 500000,10);

【三】下图中的说明:由于当前的版本不支持limit存在于in中,解决方法是采用多表查询

06 count优化

【一】count是一个聚合函数,用于求取符合条件且参数不为null的总的记录数的。

【二】count求取符合条件的总的数据量的快慢取决于存储引擎的处理方式:

    ① MySIAM存储引擎中,它会自动统计表中总的记录数,因此在执行count(*)的时候会直接返回总行数,但一旦在select语句上加了where条件,执行效率仍然是很低的,即,MySIAM存储引擎仅仅是在查询某张表的总数据量时的效率较高。

     ② InnoDB存储引擎即使没有写where条件,它在查询符合条件的总的数据量时仍然是将数据从磁盘中一行一行读出来,然后再进行累积计数,它目前并没有好的优化策略,如果要对count进行优化,只能自己手动进行计数了:比如可以借助redis数据库。

         总之,在大数据量的情况下,InnoDB存储引擎执行count操作的效率是非常低的,且目前没有比较好的优化思路,非要优化你可以自己手动计数,可以使用redis数据库相关的功能实现。

【三】count的用法:

    ① 介绍:count是一个聚合函数,用于记录参数不为null的总的记录数

    ② 常见用法:count(*)、count(主键)、count(字段)、count(某一个数)  ---> count(某一个数)的效果和count(*)、count(主键)一样

    ③ 在查询某个表的查询记录数的时候,count(*)的效率要高于其他三种。

07 update优化

【一】说明:InnoDB的行锁是根据索引加的锁,而不是针对记录加的锁,并且索引不能失效,否则行锁会升级成表锁,并发性能将会降低。

【二】优化:在使用update语句时,更新条件使用索引字段,而不要使用没有索引的字段,否则并发行锁将会升级成表锁,并发性能降低。

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

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

相关文章

【代码】集合set

哈喽大家好,我是学霸小羊,今天来讲一讲集合(set)。 在数学上,集合长这样: 那今天就来讲一讲编程上的集合。 集合的定义:把一些元素按照某些规律放在一起,就形成了一个集合。比如说…

PostgreSQL的学习心得和知识总结(一百五十四)|高级数据结构和算法之快速排序算法quicksort的实现及使用

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…

鸿蒙UI系统组件16——富文本编辑器(RichEditor)

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。 RichEditor是支持图文混排和文本交互式编辑的组件,通常用于响应用户的对…

豆包MarsCode 合伙人计划限时招募中,推广最高赢万元现金!

豆包MarsCode 合伙人计划正式上线啦!作为官方推出的推广激励项目,豆包MarsCode 编程助手号召和鼓励所有用户向我们推荐新用户。 现在正式开启首轮合伙人招募,诚邀各位有意愿推广普及 AI 编程产品的伙伴成为我们的合伙人,全国限量…

【Linux】操作系统基础

1.冯诺依曼体系结构介绍 冯诺依曼体系结构如下: 在上图中「输⼊设备」和「输出设备」⼀般被称为计算机的外设,⽽「存储器」在冯 诺依曼体系结构中表示「内存」 输⼊设备⼀般包括:⽹卡、磁盘、键盘、触摸屏等 输出设备⼀般包括:…

用 logfire 提高应用的可观测性

Logfire是由 Pydantic 团队打造的平台, 还有供 app 使用的 library, 我们经常提到对应用要做 LMT(Log, Metrics, Trace), Logfire 可以用来收集、存储、分析和可视化日志数据和应用性能指标。通过集成日志和度量,Logfire 提供了一个统一的界面来管理应用程序和系统的…

时间序列预测(一)——线性回归(linear regression)

目录 一、原理与目的 1、线性回归基于两个的假设: 2、线性回归的优缺点: 3、线性回归的主要目的是: 二、损失函数(loss function) 1、平方误差损失函数(忽略了噪声误差) 2、均方误差损失函数 三、随…

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1:正文 一般的我们写springboot项目时配置文件是这个样子的: appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…

【Java学习笔记】多线程

当我们在饭店聚餐时,多人同时吃一道菜的时候很容易发生争抢。例如,上了一道好菜,两个人同时夹这道菜,一人刚伸出筷子,结果伸到的时候菜已经被夹走了。为了避免这种现象,必须等一人 夹完一口后,另…

【大数据技术基础 | 实验一】配置SSH免密登录

文章目录 一、实验目的二、实验要求三、实验原理(一)大数据实验一体机(二)SSH免密认证 四、实验环境五、实验内容和步骤(一)搭建集群服务器(二)添加域名映射(三&#xff…

工业物联网关-ModbusTCP

Modbus-TCP模式把网关视作Modbus从端设备,主端设备可以通过Modbus-TCP协议访问网关上所有终端设备。用户可以自定义多条通道,每条通道可以配置为TCP Server或者TCP Slave。注意,该模式需要指定采集通道,采集通道可以是串口和网口通…

51WORLD携手浙江科技大学,打造智慧校园新标杆

当前,国家教育数字化战略行动扎实推进,高等教育数字化转型步伐加快。 紧抓数字教育发展战略机遇,浙江科技大学联合51WORLD、正方软件股份有限公司(简称:正方软件),共同研发打造浙科大孪生数智校…

为什么很多人宁愿加钱买港版,也不愿买国行 iPhone 16

最近的 iPhone 16 市场,真的是倒反天罡,攻守异形啊。 过去,港版 iPhone 都是性价比的次选,便宜个 10% 都得考虑考虑。但今年,港版 iPhone 16 的价格,反而比国行还贵。 比如,闲鱼上某个卖家&am…

Java消息摘要:MD5验证数据完整性、密码的加密与校验

MD5(Message-Digest Algorithm 5)是一种被广泛使用的密码散列函数,是一种不可逆的加密算法,该算法可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完…

【工具变量】知识产权示范城市DID(2000-2023年)

数据简介:为深入贯彻落实《国家知识产权战略纲要》,强化知识产权治理效能,国家知识产权局制定了《国家知识产权试点、示范城市(城区)评定和管理办法》,知识产权示范城市成为知识产权强国战略落地的城市支撑…

echarts 入门

工作中第一次碰到echarts&#xff0c;当时有大哥。二进宫没办法&#xff0c;只能搞定它。 感觉生活就是这样&#xff0c;不能解决的问题总是会反复出现。通过看视频、查资料&#xff0c;完成了工作要求。写一篇Hello World&#xff0c;进行备查。 基本使用 快速上手 <!DO…

QNAP新手必看!轻松搞定反向代理设置

反向代理是一种服务器配置&#xff0c;允许你通过一个域名或者IP地址来访问不同的内部应用服务。在QNAP NAS上配置反向代理可以提升应用程序的安全性和可访问性。 准备工作 确保QNAP NAS已连接网络并有公网IPv4/IPv6。 确认已启用Web服务 步骤 1&#xff1a;启用Web服务 登…

相机光学(三十九)——光学暗角与机械暗角

1.什么是暗角 在玩摄影一段时间,拍摄一定数量的照片之后,每个人都会不可避免地遇上一个新问题,那就是暗角现象。所谓暗角,是指在拍摄亮度均匀的场景时,画面的四角却出现与实际景物不符的、亮度降低的现象,又被称为“失光“。 2.暗角的成因 (1)边角的成像光线与镜头光轴…

【智能控制】第2章 专家系统,专家控制,模糊关系,模糊推理,专家PID控制

目录 2.1 专家系统 2.1.1 专家系统概述 2.1.2 专家系统构成 2.1.3 专家系统的建立 1&#xff0e;知识库 2&#xff0e;推理机 3&#xff0e;知识的表示 4&#xff0e;专家系统开发语言 5&#xff0e;专家系统建立步骤 第二节 专家控制 2&#xff0e;功能 3 与专家…

三、账号密码存储

使用Playfers存储 Unity本地持久化类Playerprefs使用详解 - PlaneZhong - 博客园 (cnblogs.com) 一、登陆界面切换 1、登陆界面的脚本&#xff08;机制类脚本&#xff09; 在这个UI上挂载一个脚本LoginWnd 先声明一下这个脚本&#xff0c;拖拽 2、在登录模块中调用 这里的l…