普通插入(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:批量插入
Insert into tb values(1,'value1'),(2,'value2'),(3,'value3');
优化方案2:手动控制事务
反例:
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
-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;
举个栗子:
'/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'
表示每一行之间采用换行符分割。为什么主键顺序插入的性能要大于乱序插入?
页分裂与页合并现象
主键顺序添加数据时的过程是怎样的?
与页分裂相对,还有页合并现象:
当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。
当页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
最后2#中被标记的数据删除,同时2#和3#进行合并:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。