30条书写高质量SQL的建议,太有用了!( 三 )


30条书写高质量SQL的建议,太有用了!

文章插图
 

30条书写高质量SQL的建议,太有用了!

文章插图
 
理由如下:
  • 当我们创建一个联合索引的时候,如(k1,k2,k3),相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引,这就是最左匹配原则 。
  • 联合索引不满足最左原则,索引一般会失效,但是这个还跟 MySQL 优化器有关的 。
12、对查询进行优化,应考虑在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描
反例:
select * from user where address ='深圳' order by age ; 
30条书写高质量SQL的建议,太有用了!

文章插图
 
正例:
添加索引 alter table user add index idx_address_age (address,age) 
30条书写高质量SQL的建议,太有用了!

文章插图
 
13、如果插入数据过多,考虑批量插入
反例:
for(User u :list){ INSERT into user(name,age) values(#name#,#age#)}正例:
//一次500批量插入,分批进行insert into user(name,age) values<foreach collection="list" item="item" index="index" separator=",">(#{item.name},#{item.age})</foreach>理由:批量插入性能好,更加省时间 。
打个比喻:假如你需要搬一万块砖到楼顶,你有一个电梯,电梯一次可以放适量的砖(最多放 500),你可以选择一次运送一块砖,也可以一次运送 500 块砖,你觉得哪个时间消耗大?
14、在适当的时候,使用覆盖索引
覆盖索引能够使得你的 SQL 语句不需要回表,仅仅访问索引就能够得到所有需要的数据,大大提高了查询效率 。
反例:
// like模糊查询,不走索引了select * from user where userid like '%123%'
30条书写高质量SQL的建议,太有用了!

文章插图
 
正例:
//id为主键,那么为普通索引,即覆盖索引登场了 。select id,name from user where userid like '%123%';
30条书写高质量SQL的建议,太有用了!

文章插图
 
15、慎用 distinct 关键字
distinct 关键字一般用来过滤重复记录,以返回不重复的记录 。在查询一个字段或者很少字段的情况下使用时,给查询带来优化效果 。但是在字段很多的时候使用,却会大大降低查询效率 。
反例:
SELECT DISTINCT * from user; 正例:
select DISTINCT name from user; 理由:带 distinct 的语句 CPU 时间和占用时间都高于不带 distinct 的语句 。
因为当查询很多字段时,如果使用 distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较、过滤的过程会占用系统资源,CPU 时间 。
16、删除冗余和重复索引
反例:
KEY `idx_userId` (`userId`)KEY `idx_userId_age` (`userId`,`age`)正例:
//删除userId索引,因为组合索引(A,B)相当于创建了(A)和(A,B)索引KEY `idx_userId_age` (`userId`,`age`)理由:重复的索引需要维护,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能的 。
17、如果数据量较大,优化你的修改/删除语句
避免同时修改或删除过多数据,因为会造成 CPU 利用率过高,从而影响别人对数据库的访问 。
反例:
//一次删除10万或者100万+?delete from user where id <100000;//或者采用单一循环操作,效率低,时间漫长for(User user:list){delete from user; }正例:
//分批进行删除,如每次500delete user where id<500delete product where id>=500 and id<1000;理由:一次性删除太多数据,可能会有 lock wait timeout exceed 的错误,所以建议分批操作 。
18、where 子句中考虑使用默认值代替 null
反例:
select * from user where age is not null; 
30条书写高质量SQL的建议,太有用了!

文章插图
 
正例:
//设置0为默认值select * from user where age>0;
30条书写高质量SQL的建议,太有用了!

文章插图
 
理由:并不是说使用了 is null 或者 is not null 就会不走索引了,这个跟 MySQL 版本以及查询成本都有关 。


推荐阅读