专栏名称: DBAplus社群
围绕数据库、大数据、PaaS云,顶级大咖、技术干货,运营几个月受众过十万!成为运维圈最专注围绕“数据”的学习交流和专业社群!欢迎投稿,加入探讨。
目录
相关文章推荐
AustinDatabases  ·  哎,马上删,马上 ·  13 小时前  
终码一生  ·  如何加快 SQL 查询速度的同时保持 ... ·  22 小时前  
数据中心运维管理  ·  弱电智能化中究竟有多少个子系统? ·  2 天前  
数据中心运维管理  ·  超大规模数据中心如何重新思考冷却效率 ·  4 天前  
数据中心运维管理  ·  锂电池火灾处理难度 ·  3 天前  
51好读  ›  专栏  ›  DBAplus社群

后端程序员书写高质量SQL的30条建议

DBAplus社群  · 公众号  · 数据库  · 2020-11-05 07:15

正文

请到「今天看啥」查看全文


user where userId like '%123' ;

正例:

select userId name from user where userId like '123%' ;


理由:

  • 把%放前面,并不走索引,如下:



  • 把% 放关键字后面,还是会走索引的。如下:



6、使用where条件限定要查询的数据,避免返回多余的行。


假设业务场景是这样:查询某个用户是否是会员。曾经看过老的实现代码是这样。。。


反例:

List < Long > userIds = sqlMap . queryList ( "select userId from user where isVip=1" );

boolean isVip = userIds.contains ( userId );


正例:

Long userId = sqlMap . queryObject ( "select userId from user where userId= 'userId' and isVip='1' " )

boolean isVip = userId!=null;


理由: 需要什么数据,就去查什么数据,避免返回不必要的数据,节省开销。


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 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。


都满足SQL需求的前提下,推荐优先使用Inner join(内连接),如果要使用left 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是等值连接,或许返回的行数比较少,所以性能相对会好一点;

  • 同理,使用了左连接,左边表数据结果尽量小,条件尽量放到左边处理,意味着返回的行数可能比较少。


10、应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。


反例:

select age







请到「今天看啥」查看全文