栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mysql 优化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql 优化

插入数据:

        批量插入:尽量避免一条一条地插入数据,因为每次插入都需要和数据库建立连接,影响性能。

insert into tb_user values(null,zhangsan),(null,lisi),(null,wangwu);

        手动事务提交:

start transaction;
insert into tb_user values(null,zhangsan),(null,lisi),(null,wangwu);
insert into tb_user values(null,zhangsan),(null,lisi),(null,wangwu);
insert into tb_user values(null,zhangsan),(null,lisi),(null,wangwu);
coommit;

        主键顺序插入:性能比主键乱序插入好。见下节主键优化

        大批量插入数据:使用load指令,将本地文件加载进数据库。

#连接客户端时,加上--local-infile
mysql  --local-infile -h -uroot -p

set global local_infile = 1;    --开启

load data local file '本地文件路径' into table 'tb_user' fields terminated by '分隔符',lines terminated by '/n';    --加载本地文件到tb_user表,每个字段以'分隔符'分割,每条记录以换行符分割
主键优化:

        InnoDB存储引擎中,表数据是根据主键顺序组织存放的,称为索引组织表。

页分裂:顺序插入时,第一页插满了,新数据会插入到第二页。因为表数据是根据主键顺序存放的,所以乱序插入时为了保证顺序插入,会将老数据拆开和新数据一起插入到新页中,重新组织链表。

页合并:删除一行记录时并不会真正删除,而是使用标记标记该行可被其他记录使用。当页中被删除的记录达到MERGE_THRESHOLD(默认50%)时,会向前或向后合并两个页。

主键设计原则:

        1.尽量降低主键长度(二级索引中数据字段记录的是主键,因此不宜过长)

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

        3.尽量不要使用UUID或者其他自然主键,因为无序且长度较大

OrderBy优化

        需要根据排序字段建立合适的索引,多字段排序时遵循最左前缀法则。

Using filesort:全盘扫描后,在排序缓冲区sort buffer中完成排序,而不是通过索引返回排序结果

Using index:通过有序索引顺序扫描直接返回有序数据,不需要额外排序

        多字段排序时,升序降序顺序一致或者都为逆序时,将using index(满足覆盖查询时),否则将using filesort。多字段排序,可根据具体的规则建立不同的升序降序索引

create index idx_aage_dphone on tb_user (asc age, desc phone)

        如果不可避免的出现filesort,可以适量排序缓冲区sort_buffer_size(默认256k)大小,以增加大数据排序量的效率(如果排序缓冲区满了,会在磁盘中排序,那个速度你懂的)

GroupBy优化

        讨论索引对分组排序的影响

对无索引字段分组的话,会出现using temporary,这个效率比较低。使用联合索引时,如果部分满足索引那么会出现using index 和using temporary。满足最左前缀法则的话,就直接using index

对于profession,age,status字段的联合索引以下语句(注意where)也是满足最左前缀法则的:

select age,count(*) from tb_user where 'profession' = '软件工程' group by age;
Limit优化

        如果limit子句起始位置很大的话,那么会很影响查询速度(越往后越大),因为mysql时从第一条开始找到起始位置的。

        官方给出的优化方案是:覆盖索引+子查询;

select * from tb_user limit 10000000,10;    --从第10000000条开始查询100条数据

select id from tb_user limit 10000000,10;    --在上述语句的基础上覆盖索引

select t.* from tb_user t ,(select id from tb_user limit 10000000,10) u 
where t.id = u.id;    --覆盖索引+子查询
Count优化

        MylSAM引擎中会把表的总行数单独记录,count(*)时直接返回该记录(查询时没有其他条件)

InnoDB引擎在count(*)时会把数据一条一条取出来,进行累加。优化思路:自己计数、自己维护。

无很好的优化方法。

count的几种用法:

        count(*):InnoDB直接做了优化,不取值,服务层直接按行累加

        count(1):不取值,对于返回的每一行放1进去(有意义吗...?),直接按行累加

        count(主键):取主键返回给服务层,按行累加(主键不可能为null,省去判断)

        count(字段):若该字段有not null字段约束,那么不会判断是否为null,取字段返回给服务层,按行累加。若没有not null约束,那么会多一步判断的操作

Update优化

        InnoDB引擎事务默认用的行锁。

--客户端A 开启事务,执行更新语句,但没提交
transaction;
update tb_user set phone = '888888' where phone = '10086';

--客户端B
update tb_user set phone = '123456' where phone = '10086';    --语句1

update tb_user set phone = '999999' where phone = '10000';    --语句2

若phone字段有索引,那么语句1将会被阻塞,语句2成功执行。此时是行锁。

若phone字段没有索引,那么行锁将升级为表锁,语句1和2都被阻塞。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025039.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号