键盘敲烂,年薪30万
目录
一、索引优化 回顾:
索引分类:
索引失效:
设计原则:
SQL性能分析
二、SQL优化 语句优化
insert语句:
主键优化:
order by优化:
group by优化:
limit 优化
count 优化
update 优化
注意:
主键索引只能有一个且必须有一个,二级索引可以有多个,如果没有主键,选唯一索引作为主键索引,如果没有唯一索引,那么mysql会创建一个隐藏字段rowid作为索引。
尽量建立联合索引,针对于数据量大(超百万),查询多的表建索引,针对于where order by group by后的字段创建索引,如果字段很长,考虑前缀索引,如果索引列不能为NULL,须在数据库字段加上not null约束,这样优化器可以更好的选择更有效的索引。
批量插入优化:
insert into user values(1, 'zhangsan'), (2,'lisi');
手动提交事务优化:
start transaction
insert into user values(1, 'zhagnsan'), (2, 'lisi'), ……
insert into user values(1000, 'wangwu'), (1001, 'zhaoliu') ……
……
commit
主键顺序插入优化:
大批量插入数据优化:
1.连接数据库时加上:
--local-infile
2.打开全局参数:
set global local infile = 1;
3.插入数据的脚本:
load data local infile '/root/sql1.log' into table 'tb_user' fields terminated by ',' line terminated by '\n';
前面提到了主键按顺序插入可提高性能,这里讲解原理。
(这里我不是很明白,摘自GPT的回答)
页分裂:
页合并:
小结:
索引的设计原则:长度尽量短,尽量有序插入。
优化准则:
注意:
创建索引默认是升序排序,asc
创建索引是指定排序规则
create index id_na_ty on tb_book(name asc, type asc);
例如:
select id, name, type from tb_book order by name asc, type asc;
-- 直接返回索引下面挂的数据,效率高
查看执行过程:
select id, name, type from tb_book order by name asc, type desc;
-- 会在缓冲区进行排序,效率不高。
查看执行过程:
小总结:
order by 查询的字段要与建立索引时字段的排序规则相同,若不同,会在缓冲区排序然后返回数据,可以在创建索引时指定排序规则
跟order by类似,建立好相应的索引,并且保证索引正确的使用规则,比如最左前缀法则。
记住:覆盖索引加子查询:
原理:原本要对数据进行排序,在挑选50条数据,现在使用索引覆盖 + 子查询 先根据id排序,排完之后直接子查询就可以啦。
select * from user where limit 10000, 50;
-- 回表查询性能低
select t.* from user t, (select if from user where order by id limit 10000, 50) s where t.id = s.id;
-- 覆盖索引 + 子查询 性能略好
count统计非空字段数量,count无法优化,但是我们要区分count()括号里的字段的含义
小结:
尽量使用count(*)
例如:user表 name字段带有索引
一个客户端执行:update user set name = 'Zhangsan' where name = 'Lisi';
一个客户端执行:update user set name = 'wangwu' where name = 'zhaoliu';
分析:
此时可以并发执行,因为索引对应的是行级锁,不会锁整张表,相反如果没有索引,或者索引失效,行级锁就会变为表锁,无法高并发。