sql优化:

1.插入语句sql优化:

insert语句优化:

1.批量插入,这样可以避免多次的和数据库交互,提高性能。建议500-1000条数据一次批量插入。

insert into t_order values('1','o1','1'),('2','o2','1'),('3','o3','1')

2.手动提交事物:避免多次的事物提交操作,当所有要插入的数据插入完成后,手动提交。

START TRANSACTION
insert into t_order values('1','o1','1'),('2','o2','1'),('3','o3','1');
insert into t_order values('4','o1','1'),('5','o2','1'),('6','o3','1');
insert into t_order values('7','o1','1'),('8','o2','1'),('9','o3','1');
COMMIT

3.主键顺序插入,表数据是根据主键顺序存放,这种存储方式被称为索引组织表,这里主要是涉及到页分裂,如果没有按照顺序插入,那么再插入的过程中,后一个值小于前面的主键值的情况,可能会出现页分裂现象,导致插入缓慢。

4.如果要大批量的插入数据,那么使用load指令来插入数据。

主键优化:

1.满足业务场景的情况下,尽量降低主键的长度;

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

3.尽量不要使用uuid或者其他自然主键,如身份证号,因为这样主键过长,且无顺序。

4.业务操作时,避免对主键的修改。

排序优化:

order by 优化:

using filesort:通过表的索引或者全表扫描,读取满足条件的数据行,然后再排序缓冲区sort buffer中完成排序,所有不是通过索引直接返回排序结果的排序都叫filesort排序。

using index :通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。

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

2.尽量使用覆盖索引。

3.多字段排序,一个升序一个降序,此时需要注意联合索引再创建时的规则(ASC/DESC)

#创建索引
CREATE INDEX index_age_time_ad  on `user`(age asc ,time desc);
#查看索引命令
show index from user

EXPLAIN select age,time from user order by age asc ,time desc 

4.如果不可避免的出现filesort ,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(m默认是256K)

group by 优化:

1.在分组操作时,建立合适的索引来提高效率

2.在索引的使用时,也需要满足最左前缀法则。

limit优化:

当我们去分页的时候,如果起始页的数据比较大时,那么mysql默认会去遍历,找到这条数据,当我们要查询的数据,有的还没有被索引覆盖,那么还会涉及到回表查询。针对这种情况,我们可以通过:

一般分页查询时,通过创建覆盖索引能较好的提升性能,可以通过覆盖索引加子查询的方式进行优化。

select a.* from user a ,(select id from user limit 1000000,10) b where a.id = b.id;

count优化:

MyisAM 引擎把一张表的总行数存在了磁盘上,所以可以直接返回总条数,效率较高

Innodb 引擎执行的时候,需要一条条的去读出来,累计计数。

count(主键)

Innodb 引擎会遍历整张表,把每一行的id都取出来,返回给服务层,服务层拿到主键后,直接进行累加。

count(字段):

有not null约束:Innodb 引擎会遍历整张表,把每一行的数据都取出来给服务层,服务层拿到数据后进行累加。

没有not null约束:Innodb 引擎会遍历整张表,把每一行数据都取出来,然后判断是否为null,不为null则加1,为null则不加。

count(1):

Innodb 引擎会遍历整张表,但不取值。服务层对返回的每一条数据都会放一个“1”进行,直接按行进行累加。

count(*):

Innodb 引擎会遍历整张表,但不取值,服务层直接按行进行累加。

性能比较:

count(字段)< count(主键) < count(1) ≈ count(*)

update优化:

Innodb是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则行锁会升级为表锁

#第一个窗口
select * from user;
begin

update user set name = "刘的士速递瑾" where name="气象"

commit;

#第二个窗口

select * from user

begin

update user set name = "赵育良" where name = "李大姐昂" 

commit;

上面的sql语句中,由于没有给name建立索引,当第一个update语句执行后,但是没有提交,第二个update语句就无法执行。

但是如果给name建立索引了,那么就只是行锁,第一个update并不会影响第二个update。

你可能感兴趣的:(mysql,sql,数据库)