广告
返回顶部
首页 > 资讯 > 数据库 >【MySQL】SQL优化(九)
  • 818
分享到

【MySQL】SQL优化(九)

mysqlsql数据库 2023-08-19 17:08:05 818人浏览 独家记忆
摘要

🚗Mysql学习·第九站~ 🚩本文已收录至专栏:MySQL通关路 ❤️文末附全文思维导图,感谢各位点赞收藏支持~ ⭐学习汇总贴,超详细思维导图:【MySQL】学习汇总(完整思维导图) 一.插入数据 (1

🚗Mysql学习·第九站~
🚩本文已收录至专栏:MySQL通关路
❤️文末附全文思维导图,感谢各位点赞收藏支持~
⭐学习汇总贴,超详细思维导图:【MySQL】学习汇总(完整思维导图)

一.插入数据

(1) 小规模数据

如果我们需要一次性往数据库表中插入多条记录:

-- 例如我们需要插入大量数据insert  into  tb_test  values(1,'tom');insert  into  tb_test  values(2,'cat');insert  into  tb_test  values(3,'jerry');....

我们可以从以下三个方面进行优化~

(1.1) 批量插入数据

由于每次insert都需要与数据库建立连接,进行网络传输导致一定的性能损失,我们可以选择一次性插入多条数据,代替一条一条插入。

-- 例如上述多条插入改为Insert  into  tb_test  values(1,'Tom'),(2,'Cat'),(3,'Jerry');

不过一次性插入数据不建议超过500~1000条,大批量数据我们也可以拆分为多个insert批量插入。

(1.2) 手动控制事务

由于mysql中事务提交的方式默认是自动提交的,也就是说当我们执行完一条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;    -- 提交事务

(1.3) 主键顺序插入

由于主键索引的存在,每次插入数据都可能会重新组织索引结构,因此,主键顺序插入,性能要高于乱序插入。

-- 主键乱序插入 : 8  1  9  21  88  2  4  15  89  5  7  3  -- 主键顺序插入 : 1  2  3  4  5  7  8  9  15  21  88  89insert  into  tb_test  values(1,'Tom'),(2,'Cat'),(3,'Jerry');  -- 顺序插入insert  into  tb_test  values(5,'Cat'),(6,'Jerry'),(4,'Tom');  -- 乱序插入

(2) 大批量数据

如果一次性需要插入大批量数据(比如: 几百万的记录),使用insert语句插入性能较低,此时可以使用Mysql数据库提供的load指令进行插入。通过load指令我们可以一次性将本地文件当中的数据全部加载进数据库表结构中。
在这里插入图片描述

可以执行如下指令,将数据脚本文件中的数据加载到表结构中:

  • (1)客户端连接服务端时,加上参数 -–local-infile
 mysql –-local-infile -u root -p  -- -–local-infile 表示需要加载本地文件
  • (2)设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set  global  local_infile = 1;
  • (3)执行load指令将准备好的数据,加载到表结构中
load  data  local  infile  '/root/sql1.log'  into  table  tb_user  fields  terminated  by  ','  lines  terminated  by  '\n' ; --  local  infile  '需要加载的文件路径'--  into  table  需要插入到哪张表--  fields terminated  by  '字段分隔符'--  lines  terminated  by  '行分隔符'

在这里插入图片描述

二.主键优化

在满足业务需求的情况下,尽量遵循以下原则设计主键。

(1) 降低主键的长度

对于一张表来说主键索引只有一个,但是二级索引可能会有很多个,在二级索引的叶子节点当中挂的就是数据的主键,因此,如果主键长度比较长且二级索引比较多,将会占用大量的磁盘空间。
在这里插入图片描述

(2) 顺序插入

在条件允许的情况下,使用AUTO_INCREMENT自增主键,顺序插入数据。

在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,行数据都是存储在聚集索引的叶子节点上的。
在这里插入图片描述

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

  • 主键顺序插入效果
  1. 从磁盘中申请页, 主键顺序插入

在这里插入图片描述

  1. 第一个页没有满,继续往第一页插入

在这里插入图片描述

  1. 当第一个也写满之后,再写入第二个页,页与页之间会通过指针连接

在这里插入图片描述

  1. 当第二页写满了,再往第三页写入

在这里插入图片描述

如此往复,没有任何额外损耗性能的情况。

  • 主键乱序插入效果
  1. 假如1#,2#页都已经写满了

在这里插入图片描述

  1. 此时再插入id为50的记录

在这里插入图片描述

  1. 按照顺序,应该存储在47之后

在这里插入图片描述

  1. 此时会开辟一个新的页 3#

在这里插入图片描述

  1. 但是并不会直接将50存入3#页,而是会将1#页后一半的数据,移动到3#页,然后在3#页,插入50。

在这里插入图片描述

  1. 移动数据,并插入id为50的数据之后,那么此时,这三个页之间的数据顺序是有问题的。 1#的下一个 页,应该是3#, 3#的下一个页是2#。 所以,此时,需要重新设置链表指针

在这里插入图片描述

上述的这种现象,称之为 “页分裂”,是比较耗费性能的操作

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

(3) 避免对主键的修改

尽量不要使用有意义的值作为主键,如身份证号,避免在进行业务操作对主键产生修改操作。这是因为插入修改删除操作都会导致数据库重新组织索引结构。

三.order by优化

(1) 排序说明

MySQL的排序,有两种方式:

  • Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。
  • Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要 额外排序,操作效率高。

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

  • 排序字段值没有索引,Using filesort

在这里插入图片描述

  • 为排序字段值创建索引后,Using index

在这里插入图片描述

(2) 相关情况

  1. 由于我们在MySQL中创建的索引,默认的叶子节点是从小到大排序的。如果我们在查询的时候,order by是从大到小即降序desc,那么除了出现 Using index, 也会出现了 Backward index scan,这个代表反向扫描索引。 在 MySQL8版本中,支持降序索引,我们也可以创建降序索引。

在这里插入图片描述

-- 语法create index 索引名 on 表名(字段名 desc);

在这里插入图片描述

  1. 排序时,也需要满足最左前缀法则(与where条件不同的是,此时必须按照创建索引时的顺序进行排序),否则也会出现 filesort。

在这里插入图片描述

因为在创建索引的时候, age是第一个 字段,phone是第二个字段,所以排序时,也就该按照这个顺序来,否则就会出现 Using filesort

  1. 在条件允许的情况下,尽量使用覆盖索引代替*,否则由于回表查询依旧会出现Using filesort

在这里插入图片描述

四.group by优化

与order by类似,分组就相当于大范围的排序。我们同样可以通过使用索引字段进行分组来提高效率。

在这里插入图片描述

此外,对于分组操作,在使用联合索引时,也是符合最左前缀法则的。例如下面:我们发现,如果仅仅根据age分组,就会出现 Using temporary ;而如果是 根据 profession,age两个字段同时分组,则不会出现 Using temporary。

在这里插入图片描述

五.limit优化

在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。这是因为当在进行分页查询时,例如执行 limit 2000000,10 ,此时需要MySQL排序前2000010 记 录,仅仅返回 2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大。

在这里插入图片描述

通过测试我们会看到,分页越往后,查询效率越低。

  • 一般在进行分页查询时,我们可以通过 覆盖索引 + 子查询 的形式进行优化以提高性能。
--  select  *  from  tb_sku limit 9000000,10;-- 例如对于上述测试示例 9000000,10 我们可以进行如下优化explain select * from tb_sku t, (select id from tb_sku order by id limit 9000000,10) a where t.id  =  a.id;

在这里插入图片描述

测试我们可以看到,耗费时间缩短了了近7秒,但是同时也增加了SQL语句复杂度,需要我们根据自身业务情况选择使用~

六.count优化

如果在数据量很大的情况下执行count操作是非常耗时的。

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

如果说要提升InnoDB表的count效率,主要的优化思路是:

  1. 自己计数,可以借助于Redis这样的数据库进行,例如,插入一条数据,进行+1记录,删除一条数据进行-1记录。

  2. 通过改进count的用法来提升count的效率。count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加,最后返回累计值,他有着如下四种不同的写法:

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

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

七.update优化

InnoDB默认事务级别使用的是行但是行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁 升级为表锁 。也就是说在开启事务时:

  • 我们能同时根据带有主键索引的不同id字段修改行记录
update  course  set  name = 'javaEE' where id  =  1 ;update  course  set  name = 'Vue' where id  =  4 ;
  • 但是无法同时根据不带索引的name字段修改行记录,因为此时行锁会升级为表锁,无法操作。
update course set name = 'SpringBoot' where name = 'PHP' ;update update course set name = 'springBoot' where name = 'js' ;

也就是说为了避免行锁升级为表锁影响执行效率,我们应当根据索引字段来进行更新操作。

八.全文概览

在这里插入图片描述

来源地址:https://blog.csdn.net/m0_66570338/article/details/131948741

您可能感兴趣的文档:

--结束END--

本文标题: 【MySQL】SQL优化(九)

本文链接: https://www.lsjlt.com/news/375691.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【MySQL】SQL优化(九)
    🚗MySQL学习·第九站~ 🚩本文已收录至专栏:MySQL通关路 ❤️文末附全文思维导图,感谢各位点赞收藏支持~ ⭐学习汇总贴,超详细思维导图:【MySQL】学习汇总(完整思维导图) 一.插入数据 (1...
    99+
    2023-08-19
    mysql sql 数据库
  • mysql系列(九)——sql优化
    一、...
    99+
    2020-12-10
    mysql系列(九)——sql优化
  • MySQL SQL优化之‘%’
    设计索引的主要目的就是帮助我们快速获取查询结果,而以%开头的like查询则不能够使用B-Tree索引。考虑到innodb的表都是聚簇表(类似于oracle中的索引组织表),且二级索引叶节点中记录的结构为(索...
    99+
    2022-10-18
  • MySQL的SQL优化
    如何获取有性能问题的sql         通过慢查询日志可以获取大部分有性能问题的SQL,但是通常对慢查询日志的分析还是有一定延迟,有些情况下还是希望实时的获取哪些SQL有性能问题,比如当前数据库服务器的压力徒增等。 slow_qu...
    99+
    2020-01-20
    MySQL的SQL优化
  • 【MySQL】sql如何优化?
    一、优化步骤 (1)通过SQL监控、请求、日志等找出耗时的SQL语句; (2)使用Explain方式查看SQL耗时的具体原因; (3)根据实际情况解决:索引、缓存、左右连接 二、Explain select_type:简单查询or复杂查询?...
    99+
    2023-09-16
    sql mysql 数据库
  • mysql的sql优化(一)
    配置慢查询日志 set global slow_query_log = [ON|OFF] set global slow_query_log_file = /sql_log/slowlog.log set global long_query...
    99+
    2021-11-19
    mysql的sql优化(一)
  • MySQL优化之三:SQL语句优化
    一 SQL语句优化的一般步骤:1 通过show status命令了解各种SQL语句的执行频率mysql> show status;      ...
    99+
    2022-10-18
  • Mysql优化-慢sql日志
    一.开启慢sql日志捕获慢sql 查询mysql是否开启慢sql捕获:show variables like ‘%slow_query_log%’; 默认为OFF,开启:set global slow_query_log=1; 查看慢...
    99+
    2018-11-19
    Mysql优化-慢sql日志
  • MySql中sql怎么优化
    这篇文章主要介绍了MySql中sql怎么优化,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、explain返回列简介1、type常用关键字...
    99+
    2022-10-19
  • 50个SQL语句(MySQL版) 问题九
    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 teacher(TId,Tname)...
    99+
    2017-08-19
    50个SQL语句(MySQL版) 问题九
  • MySQL优化之二:My SQL Server性能优化
    1 安装优化一般说来,系统功能越多越复杂,性能就会越差。因此在编译安装MySQL时,仅安装需要的功能模块。如存储引擎、需要的字符集等,让系统尽可能的简单。2 日志设置优化由于日志记录直接带来的性能损耗就是数...
    99+
    2022-10-18
  • 【MySQL进阶教程】SQL优化
    前言 本文为 【MySQL进阶教程】SQL优化 相关知识,下边将对主键优化,order by优化,group by优化,limit优化,count优化,update优化等进行详尽介绍~ &...
    99+
    2023-09-21
    mysql sql 数据库
  • 【mysql】SQL优化15种方法
    关于SQL优化15种方法 为什么进行SQL优化?1.避免使用select *2.用union all代替union3.小表驱动大表4.批量操作5.多用limit6.in中值太多7.增量查询8.高效的分页9.用连接...
    99+
    2023-08-18
    sql mysql
  • MySQL的慢SQL怎么优化
    本篇内容主要讲解“MySQL的慢SQL怎么优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL的慢SQL怎么优化”吧!索引类似大学图书馆建书目索引,可以...
    99+
    2022-10-18
  • 50个SQL语句(MySQL版) 问题十九
    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 teacher(TId,Tname)...
    99+
    2022-04-03
    50个SQL语句(MySQL版) 问题十九
  • SQL Server 2017 AlwaysOn AG 自动初始化(九)
    SQL Server VDI备份原理分析SQL Server提供了虚拟设备接口(VDI)API,用于帮助独立的应用程序提供商,支持将SQL Server的备份和恢复操作集成到他们的产品中。这些API设计为提...
    99+
    2022-10-18
  • mysql的sql语句如何优化
    要优化MySQL的SQL语句,可以采取以下几个方法:1. 使用索引:使用适当的索引可以大大提高查询性能。可以使用`EXPLAIN`命...
    99+
    2023-09-27
    mysql sql
  • MySQL学习笔记(18):SQL优化
    本文更新于2019-08-18,使用MySQL 5.7,操作系统为Deepin 15.4。 目录优化SQL语句的步骤通过SHOW STATUS了解SQL语句的执行情况定位执行效率低下的SQL语句通过EXPLAIN或DESC分析SQ...
    99+
    2016-01-24
    MySQL学习笔记(18):SQL优化
  • 基于MySQL 的 SQL 优化总结
    在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务。例行 SQL 优化,不仅可以提高程序性能,还能减低线上故障的概率。 目前常用的 SQL 优化方式包括但不限于:业务层优化、SQL 逻辑优化、索引优化等。其中索...
    99+
    2017-06-28
    基于MySQL SQL 优化总结
  • MySQL优化SQL语句的技巧
    在面对不够优化、或者性能极差的SQL语句时,我们通常的想法是将重构这个SQL语句,让其查询的结果集和原来保持一样,并且希望SQL性能得以提升。而在重构SQL时,一般都有一定方法技巧可供参考,本文将介绍如何通过这些技巧...
    99+
    2022-05-24
    MySQL 优化 mysql sql语句 mysql 优化sql语句
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作