sql优化
插入数据
大批量插入数据
主键顺序插入性能高于乱序插入
load data local infile '/root/load_user_100w_sort.sql' into table tb_user
fields terminated by ',' lines terminated by '\n' ;
主键优化
这个黄色的都是一个一个Page
主键乱序插入之后会变成1-3-2,又开辟新页又要改变指针顺序
当页中删除的记录达到 MERGE_THRESHOLD (默认为页的 50% ), InnoDB 会开始寻找最靠近的页(前 或后)看看是否可以将两个页合并以优化空间使用。
- 尽量降低主键的长度
- 插入数据尽量选择顺序插入,选择自增主键
- 尽量不要使用uuid做主键或其他自然主键,比如身份证号
- 业务操作时,避免对主键的修改
order by优化
using filesort
using index
-- 创建索引
create index idx_user_age_phone_aa on tb_user(age,phone);explain select id,age,phone from tb_user order by age desc , phone desc ; 1
也出现 Using index , 但是此时 Extra 中出现了 Backward index scan ,这个代表反向扫描索
引,因为在 MySQL 中我们创建的索引,默认索引的叶子节点是从小到大排序的,而此时我们查询排序 时,是从大到小,所以,在扫描时,就是反向扫描,就会出现 Backward index scan 。 在
MySQL8 版本中,支持降序索引,我们也可以创建降序索引。
explain select id,age,phone from tb_user order by phone , age;
排序时 , 也需要满足最左前缀法则 , 否则也会出现 filesort 。因为在创建索引的时候, age 是第一个
字段, phone 是第二个字段,所以排序时,也就该按照这个顺序来,否则就会出现 Using filesort。
explain select id,age,phone from tb_user order by age asc , phone desc ;
因为创建索引时,如果未指定顺序,默认都是按照升序排序的,而查询时,一个升序,一个降序,此时 就会出现Using filesort 。
- 创建联合索引(age 升序排序,phone 倒序排序)
create index idx_user_age_phone_ad on tb_user(age asc ,phone desc); explain select id,age,phone from tb_user order by age asc , phone desc ;
- 升序/降序联合索引结构图示:
group by优化
我们在针对于 profession , age , status 创建一个联合索引。
create index idx_user_pro_age_sta on tb_user(profession , age , status);
如果仅仅根据 age 分组,就会出现 Using temporary ;而如果是 根据 profession,age两个字段同时分组,则不会出现 Using temporary 。原因是因为对于分组操作, 在联合索引中,也是符合最左前缀法则的。
A. 在分组操作时,可以通过索引来提高效率。
B. 分组操作时,索引的使用也是满足最左前缀法则的。
这样也可以
select profession, count(*) from tb_user where profession = '软件工程' group by age;
limit优化
越往后,分页查询效率越低
一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查
询形式进行优化
explain select * from tb_sku t , (select id from tb_sku order by id
limit 2000000,10) a where t.id = a.id;
count优化
按照效率排序的话, count( 字段 ) < count( 主键 id) < count(1) ≈ count(*) ,所以尽量使用 count(*) 。
update优化
InnoDB 的行锁是针对索引加的锁,不是针对记录加的锁 , 并且该索引不能失效,否则会从行锁 升级为表锁 。
update course set name = 'SpringBoot' where name = 'PHP' ;
name没有索引,所以锁会升级为表锁
视图
创查修删
这里面的修改就是把整张表都改了
增删改查
create or replace view stu_v_1 as select id,name from student where id <= 10 ;
select * from stu_v_1;
insert into stu_v_1 values(6,'Tom');
insert into stu_v_1 values(17,'Tom22');
insert into会在基础表中插入数据
如果指定了条件,然后我们在插入、修改、删除数据时,做到必须满足条件才能操作:
with cascaded check option
创了v3,能加11,能加17(创建v3没有cascaded就不管<15的条件),不能加28(v3关联了v2,v2有cascaded就会关联v1和自己)
加了with cascaded就会检查当前视图以及关联的所有视图(select后面的),如果不加就不会检查 当前视图
视图插入数据时要求视图与基础表一一对应