批量插入:尽量避免一条一条地插入数据,因为每次插入都需要和数据库建立连接,影响性能。
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都被阻塞。



