后端程序员书写高质量SQL的30条建议( 二 )
boolean isVip = userIds.contains ( userId );
正例:
Long userId = sqlMap.queryObject ( "select userId from user where userId= 'userId' and isVip='1' ")
boolean isVip = userId!=;
理由:需要什么数据 , 就去查什么数据 , 避免返回不必要的数据 , 节省开销 。
7、尽量避免在索引列上使用mysql的内置函数 。
业务需求:查询最近七天内登陆过的用户(假设loginTime加了索引)
反例:
select userId , loginTime from loginuser where Date_ADD ( loginTime , Interval 7 DAY) >=now;
正例:
explain select userId , loginTime from loginuser where loginTime >= Date_ADD (NOW, INTERVAL -7 DAY);
理由:
- 索引列上使用mysql的内置函数 , 索引失效;
文章插图
- 如果索引列不加内置函数 , 索引还是会走的 。
文章插图
8、应尽量避免在where子句中对字段进行表达式操作 , 这将导致系统放弃使用索引而进行全表扫 。
反例:
select * from user where age-1=10;
正例:
select * from tab1 t1 left join tab2 t2 on t1.size = t2.size where t1.id>2;
select * from user where age =11;
理由:虽然age加了索引 , 但是因为对它进行运算 , 索引直接迷路了 。。。
文章插图
9、Inner join 、left join、right join , 优先使用Inner join , 如果是left join , 左边表结果尽量小 。
- Inner join 内连接 , 在两张表进行连接查询时 , 只保留两张表中完全匹配的结果集;
- left join 在两张表进行连接查询时 , 会返回左表所有的行 , 即使在右表中没有匹配的记录;
- right join 在两张表进行连接查询时 , 会返回右表所有的行 , 即使在左表中没有匹配的记录 。
反例:
select * from tab1 t1 left join tab2 t2 on t1.size = t2.size where t1.id>2;
正例:
select * from (select * from tab1 where id >2) t1 left join tab2 t2 on t1.size = t2.size;
理由:
- 如果inner join是等值连接 , 或许返回的行数比较少 , 所以性能相对会好一点;
- 同理 , 使用了左连接 , 左边表数据结果尽量小 , 条件尽量放到左边处理 , 意味着返回的行数可能比较少 。
反例:
select age,name from user where age <>18;
正例:
//可以考虑分开两条sql写
select age,name from user where age <18;
select age,name from user where age >18;
理由:使用!=和<>很可能会让索引失效 。
文章插图
11、使用联合索引时 , 注意索引列的顺序 , 一般遵循最左匹配原则 。
表结构:(有一个联合索引idxuseridage , userId在前 , age在后)
CREATE TABLE `user`(
`id` int (11) NOT AUTO_INCREMENT,
`userId` int(11) NOT ,
`age` int (11) DEFAULT ,
`name` varchar (255) NOT ,
PRIMARY KEY (`id`),
KEY `idx_userid_age` (`userId`,`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
反例:
select * from user where age =10;
文章插图
正例:
//符合最左匹配原则
select * from user where userid=10 and age =10;
//符合最左匹配原则
select * from user where userid =10;
文章插图
文章插图
理由:
- 当我们创建一个联合索引的时候 , 如(k1,k2,k3) , 相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引 , 这就是最左匹配原则;
- 联合索引不满足最左原则 , 索引一般会失效 , 但是这个还跟Mysql优化器有关的 。
反例:
select * from user where address ='深圳' order by age ;
文章插图
正例:
添加索引
alter table user add index idx_address_age (address,age)
- 现状|程序员现状揭秘:平均年薪20.36万,Java人才需求量最大
- 联网时代|34岁转行做程序员是否还有成功的机会
- 检查|填补软件开发市场空白,飞算全自动软件工程平台瞄准全自动后端微服务开发
- 程序员学英语第1天——JavaScript 程序测试的介绍1
- 这些错误,程序员经常会犯,你了解过吗?
- 程序员面试主要看哪些 该怎么准备面试内容
- 中国程序员最容易发音错误的单词,看看你有没有读错
- 程序员大佬整理的300本编程电子书,整整12个G你想学的都有
- Rust能不能做后端开发语言?
- 程序员年包90w,回老家被月薪3800表哥怼,催他赶紧上岸