一文搞懂SQL优化——如何高效添加数据

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: **SQL优化关键点:**1. **批量插入**提高效率,一次性建议不超过500条。2. **手动事务**减少开销,多条插入语句用一个事务。3. **主键顺序插入**避免页分裂,提升性能。4. **使用`LOAD DATA INFILE`**大批量导入快速。5. **避免主键乱序**,减少不必要的磁盘操作。6. **选择合适主键类型**,避免UUID或长主键导致的性能问题。7. **避免主键修改**,保持索引稳定。这些技巧能优化数据库操作,提升系统性能。

一、SQL优化

1.高效添加数据的几种方式

普通插入(Insert语句)

先回顾一下向数据库中添加数据的基本操作:

当我们想要向数据库中的表tb中插入一条数据时,可以采用insert into语句:

insert into tb values(1,'value1');

当我们想要向数据库插入多条数据时,可以执行多条insert into语句:

insert into tb1 values(1,'value1');
insert into tb2 values(2,'value2');
insert into tb3 values(3,'value3');
.....

但是当想插入数据很多时,行数会非常密集,而且代码要多次请求数据库,每次请求都会消耗一定的性能,要怎样进行优化呢?

优化方案1:批量插入

  • 一般情况下都采用批量插入来使得添加数据更高效
  • 批量插入的思想就是把多行数据压缩成一行,只需要远程请求一次数据库,且代码更加简洁
  • 但是一次性批量插入的数据建议控制在500条之内,如果多于500条,则应该分多个批次处理
Insert into tb values(1,'value1'),(2,'value2'),(3,'value3');

优化方案2:手动控制事务

  • 通过手动控制事务添加数据有多种好处
  • 一般情况下,MySQL自动为每条插入语句创建一个事务,这样可能会导致大量的日志记录,从而降低系统性能。通过手动控制事务,可以将多条执行单元合并为一个事务,从而避免了多个事务的开销。
  • 手动控制事务可以帮助我们保证数据的完整性和一致性。

反例:

Insert into tb values(1,'value1'),(2,'value2'),(3,'value3');
Insert into tb values(4,'value1'),(5,'value2'),(6,'value3');
Insert into tb values(7,'value1'),(8,'value2'),(9,'value3');

正例:

start transaction;
Insert into tb values(1,'value1'),(2,'value2'),(3,'value3');
Insert into tb values(4,'value1'),(5,'value2'),(6,'value3');
Insert into tb values(7,'value1'),(8,'value2'),(9,'value3');
commit;

优化方案3:主键顺序插入

  • 不管数据量如何,推荐采用主键顺序插入来添加数据。
  • 主键顺序插入,性能要高于乱序插入。原理见后续的主键优化部分。
#主键乱序插入 : 6 2 9 7 2  
#主键顺序插入 : 1 2 4 6 8

优化方案4:load指令添加数据

如果一次性需要插入大批量数据(比如几百万的记录),使用insert语句可能需要花费几十分钟,此时可以使用MySQL数据库提供的load指令,这个过程只需要花费几十秒。

如何采用load指令大批量添加数据?

  • 如果是常规的连接数据库,只需要输入以下指令:
mysql -u root -p
  • 如果需要用load指令,需要额外添加-local-infile参数:
mysql –-local-infile -u root -p
  • 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关:
set global local_infile = 1;
  • 我们也可以事先通过以下指令来查看local_infile全局参数是否开启:
  • 如果local_infile显示为0,则表示开关并未开启,则需要手动设置为1。
select @@local_infile;
  • 结果显示如下:

image-20240327211844684.png

举个栗子:

  • 假设要上传100万条数据,要上传的文件路径是'/root/load_user_100w_sort.sql',则往表tb1中添加数据的完整load指令是:
load data local infile '/root/load_user_100w_sort.sql' into table tb1 fields terminated by ',' lines terminated by '\n' ;
  • 其中,
  • load data local infile是固定格式;
  • into table tb1表示向表tb1添加数据;
  • fields terminated by ','表示每一个字段之间采用逗号分割;
  • lines terminated by '\n'表示每一行之间采用换行符分割。

2.主键优化的原理

为什么主键顺序插入的性能要大于乱序插入?

  • 首先了解在InnoDB存储引擎中数据的组织方式:在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表
  • 在索引组织表中,页是InnoDB磁盘管理的最小单元,其固定大小为16K。页可以为空,也可以填充一半,也可以填充满。每个页至少包含2行数据(如果只包含一行数据则是链表结构;如果一行数据过大超过阈值会导致行溢出),根据主键排列。

image-20240327215053009.png

页分裂与页合并现象

主键顺序添加数据时的过程是怎样的?

  • 主键顺序插入,就是先在第一个页中填写数据,如果第一个页满了就写第二个页中,依此类推
  • 从磁盘中申请一页,主键按照顺序进行插入

image-20240327215640423.png

  • 当第一页存满之后,会继续申请第二页,页与页之间通过双向指针进行连接;当第二页也存满,就会申请第三页;
    image-20240327220002356.png

主键乱序添加数据时的过程是怎样的?

  • 主键乱序插入,不是依此往后插入,因为叶子节点主键之间是有序的,所以就产生了页分裂现象
  • 假设1页和2页都已经存满,而此时主键50想要插入,不会直接写入新的页,因为索引结构的叶子节点是有顺序的。
  • 按照顺序,主键50应该存储在47之后。

image-20240327220908962.png

image-20240327220914166.png

  • 但1页显然已经存满,随后会进行“页分裂”的过程,即先开启第三页,然后将1页后一半的数据,移动到3页,然后在3页中插入50。

image-20240327221552343.png

  • 最后2#和3#两页位置互换,以符合主键排序规则。最终过程如下:

image-20240327221635696.png

与页分裂相对,还有页合并现象:

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

image-20240327222057379.png

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

image-20240327222304251.png

最后2#中被标记的数据删除,同时2#和3#进行合并:

image-20240327223818964.png

3.总结

  • 插入多条数据时,尽量选择批量插入
    • 因为批量插入只需要远程请求一次数据库,且代码更加简洁
  • 插入多条数据时,尽量选择手动控制事务插入
    • 因为通过手动控制事务,可以将多条执行单元合并为一个事务,从免了多个事务的开销,同时保证数据的完整性和一致性。
  • 插入大量数据时,选择MySQL提供的load指令插入的效率要大于Insert语句
  • 插入数据时,尽量选择主键顺序插入,选择使用AUTO_INCREMENT自增主键。
    • 因为当主键乱序插入时,会产生“页分裂”,消耗性能
  • 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
    • 因为每次生成的UUID之间无序,插入时为主键乱序插入,会产生“页分裂”,消耗性能
  • 业务操作时,避免对主键的修改。
    • 因为修改主键后还需对索引结构进行修改,花费代价较大。
  • 满足业务需求的情况下,尽量降低主键的长度。
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
SQL 自然语言处理 数据库
【Azure Developer】分享两段Python代码处理表格(CSV格式)数据 : 根据每列的内容生成SQL语句
本文介绍了使用Python Pandas处理数据收集任务中格式不统一的问题。针对两种情况:服务名对应多人拥有状态(1/0表示),以及服务名与人名重复列的情况,分别采用双层for循环和字典数据结构实现数据转换,最终生成Name对应的Services列表(逗号分隔)。此方法高效解决大量数据的人工处理难题,减少错误并提升效率。文中附带代码示例及执行结果截图,便于理解和实践。
|
4月前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
|
1月前
|
SQL 存储 自然语言处理
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
|
1月前
|
SQL 数据挖掘 关系型数据库
【SQL 周周练】一千条数据需要做一天,怎么用 SQL 处理电表数据(如何动态构造自然月)
题目来自于某位发帖人在某 Excel 论坛的求助,他需要将电表缴费数据按照缴费区间拆开后再按月份汇总。当时用手工处理数据,自称一千条数据就需要处理一天。我将这个问题转化为 SQL 题目。
92 12
|
1月前
|
SQL 数据采集 资源调度
【SQL 周周练】爬取短视频发现数据缺失,如何用 SQL 填充
爬虫爬取抖音和快手的短视频数据时,如果遇到数据缺失的情况,如何使用 SQL 语句完成数据的补全。
63 5
|
3月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
4月前
|
SQL 关系型数据库 MySQL
基于SQL Server / MySQL进行百万条数据过滤优化方案
对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
152 9
|
3月前
|
SQL 容灾 关系型数据库
阿里云DTS踩坑经验分享系列|DTS打通SQL Server数据通道能力介绍
SQL Server 以其卓越的易用性和丰富的软件生态系统,在数据库行业中占据了显著的市场份额。作为一款商业数据库,外部厂商在通过解析原生日志实现增量数据捕获上面临很大的挑战,DTS 在 SQL Sever 数据通道上深研多年,提供了多种模式以实现 SQL Server 增量数据捕获。用户可以通过 DTS 数据传输服务,一键打破自建 SQL Server、RDS SQL Server、Azure、AWS等他云 SQL Server 数据孤岛,实现 SQL Server 数据源的流动。
211 0
阿里云DTS踩坑经验分享系列|DTS打通SQL Server数据通道能力介绍
|
5月前
|
SQL Oracle 关系型数据库
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
|
6月前
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
150 11