所有内容均为测试可用,真实
当前位置:绿茶加糖-郭保升 > 数据库资料 > 正文

编写高质量SQL语句的30条建议

1、查询SQL尽量不要使用select *,而是select具体字段

反例:select * from employee;

正例:select id,name from employee;
理由:只取需要的字段,节省资源、减少网络开销。

select *进行查询时,很可能就不会使用到覆盖索引了,就会造成回表查询

2、如果知道查询结果只有一条或者只要最大/最小一条记录,建议用limit 1

反例:select id,name from employee where name=jay

正例:select id,name from employee where name='jay' limit 1;

理由:加上limit 1 后,只要找到了对应的一条记录,就不会继续向下扫描了,效率将会大大提高。

3、应尽量避免在where子句中使用or来连接条件

反例:select * from user where usered=1 or age=18

正例:(使用union all  )

select * from user where usered=1 

union all

select * from user where age=18

理由:使用or可能会使索引失效,从而全表扫描。

4、优化limit分页

反例:select id, name, age from employee limit 10000,10

正例:select id, name from employee whereid>10000 limit 10;

理由:当偏移量最大的时候,查询效率就会越低,因为Mysql并非是跳过偏移量直接去取后面的数据,而是先把偏移量+要取的条数,然后再把前面偏移量这一段的数据抛弃掉再返回的。

5、优化你的like语句

反例:select userld, name from user where userld like '% 123';

正例:select userld, name from user where userld like '123%;

理由:日常开发中,如果用到模糊关键字查询很容易想到like,但是like很可能让你的索引失效。把%放前面,并不走索引;把%放关键字后面,还是会走索引的。

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

反例:

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

boolean isVip = userlds.contains(userld)

正例:

Long userld = sqlMap.queryObject("select userld from

user where userld='userld' and isVip='1'")

boolean isVip = userld! =null;

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

7、尽量避免在索引列上使用mysqI的内置函数

反例:

select userld, loginTime from loginuser where Date_ADD(loginTime, interval 7

DAY) >=now();

正例:

explain select userld, loginTime from loginuser where loginTime >=

Date ADD(NOW(), INTERVAL -7 DAY);

理由:索引列上使用mysql的内置函数,索引失效;如果索引列不加内置函数,索引还是会走的。

8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫

反例:

select * from user where age-1 =10;

正例:

select * from user where age =11;

理由:虽然age加了索引,但是因为对它进行运算,索引直接迷路。

9、Inner join、left join、 right join,优先使用

Inner join,如果是left join,左边表结果尽量小

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

11、使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则

反例:

select * from user where age = 10;

正例:

//符合最左匹配原则

select * from user where userid=10 and age =10;

//符合最左匹配原则

select * from user where userid =10;

理由:联合索引不满足最左原则,索引一般会失效,但是这个还跟Mjsql优化器有关的。(案例表结构:userid在age之前)

12、对查询进行优化,应考虑在 where 及orderby 涉及的列上建立索引,尽量避免全表扫描

13、如果插入数据过多,考虑批量插入

14、在适当的时候,使用覆盖索引

15、慎用distinct关键字

16、删除冗余和重复索引

17、如果数据量较大,优化你的修改/删除语句

18、where子句中考虑使用默认值代替null

19、不要有超过5个以上的表连接

理由:

(1)连表越多,编译的时间和开销也就越大。

(2)把连接表拆开成较小的几个执行,可读性更高。

(3)如果一定需要连接很多表才能得到数据,那么意味着糟糕的设计了。

20、exist & in的合理利用

假设表A表示某企业的员工表,表B表示部门表,查询所有部门的所有员工,很容易有以下SQL:

select * from A where deptld in (select deptld from B);

这样写等价于:

先查询部门表

B select deptld from B

再由部门deptld,查询A的员工

select * from A where A.deptld=B,deptld

可以抽象成这样的一个循环

List<> resultSet ;

for(int i=0;i<B.length;i++){

for(int j=0;j<A.length;j++)i

if(A[i].id==B[jl.id){

resultSet.add(Alil);

break;

  }

}

可以用exists实现一样的查询功能

select * from A where exists (select 1 from B where A.deptld= B.deptld);

exists查询的理解就是,先执行主查询,获得数据后,再放到子查询中做条件验证,根据验证结果(true或者false)来决定主查询的数据结果是否得意保留。

21、尽量用 union all 换 union

22、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型。

23、索引不宜太多,一般5个以内

24、尽量避免向客户端返回过多数据量

25、索引不适合建在有大量重复数据的字段上,如性别这类型数据库字段。

26、当在SOL语句中连接多个表时,请使用表的别名,并把别名前缀于每一列上,这样语义更加清晰。

27、尽可能使用varchar/nvarchar 代替char/nchar

28、为了提高group by 语句的效率,可以在执行到该语句前,把不需要的记录过滤掉。

29、如何字段类型是字符串,where时一定用引号括起来,否则索引失效。

30、使用explain 分析你SOL的计划日常开发写SQL的时候,尽量养成一个习惯。

用explain分析一下你写的SQL,尤其是走不走索引这一块。

explain select * from user where userid=10086 or age =18;

版权保护: 本文由 绿茶加糖-郭保升 原创,转载请保留链接: https://www.guobaosheng.com/shujuku/82.html