SQL语句编写注意事项

Posted 独赏孤舟蓑笠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL语句编写注意事项相关的知识,希望对你有一定的参考价值。

1、SQL编写注意事项

1.1 null 列

  null 列使用索引是无意义的,任何包含null 值的列都不会包含在索引中。因此where 语句中的is null 或者 is not null 的语句,导致索引失效。

1.2 concat 或 ||

  concate 或 || 是mysql 和 oracle 的字符串连接操作,如果对列进行函数操作,就会忽略索引的使用,比如下面的查询语句:

  

-- 忽律索引
select ... from .. where first_name || ‘‘ || last_name = bill gates ;
-- 使用索引
select ... from .. where first_name = bill and last_name = bill gates ;

1.3 like 

  使用like进行模糊查询时,如果通配符%在首位则索引会失效,如下sql语句:

 

-- 无法使用索引
select .. from .. where name like%t%
-- 可以使用索引
select .. from .. where name like t% ;

1.4 order by

  order by 子句中不要使用非索引列或嵌套表达式,这样都会导致性能降低。

1.5 使用 !=或<> 操作会使索引失效

-- 索引无效
select .. from .. where sal != 3000 ;
select .. from .. where sal <>3000 ;

1.6  使用 or 需要注意

1、or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”会得到更好的效果。

2、如果or 两边字段都有索引,用explain 也可能出现索引失效的情况

对于使用or导致索引失效的情况
select id
from t where c1=1 or c2=2 改为 select id from t where c1=1 UNION ALL select id from t where c2=2

1.7 where 和 having

  select .. from .. on .. where .. group by .. having .. order by .. limit ..,以上是sql语句的语法结构,其中on、where和having是有过滤行为的,过滤行为越能提前完成就越可以减少传递给下一个阶段的数据量,因此如果在having中的过滤行为能够在where中完成,则应该优先考虑where来实现。

1.8 exists 和 in 的选择

  

select * from 表A where id in (select id from 表B)
相当于
select * from 表A where id exits(select id from 表B where 表B.id =表A.id)

在选择使用exits 和 in 的原则根据驱动顺序的进行选择,如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以

1、当A表数据量大,B表数据量小情况下使用IN

2、当B表数据量大,A表数据量小使用exitsts

关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的SQL语句?

select colname … from A表 where a.id not in (select b.id from B表)
修改为:
select  colname … from A表 left join B 表 where a.id=b.id and b.id is null

1.9 where 后面的‘=‘后面使用函数、算术运算或其他表达式运算,系统将可能无法正确使用索引

select id from t where num/2=100
可以更改为
select id from t where num=100*2 (该方法索引不失效)

select id from t where substring(name,1,3)=abc
可以更改

select id from t where name like "abc%"

1.10 避免对where 后面的字段进行隐私类型转换

where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型。

select name from t where int(age)=20 对字段进行了类型转换,索引失效

 

  

以上是关于SQL语句编写注意事项的主要内容,如果未能解决你的问题,请参考以下文章

SQL Select 语句的用法

Microsoft SQL Server 代码片段收集

编写代码片段的更简洁的方法

数据库查询语句调优> 对象的设计,常规语句的编写,执行计划定向优化

sql语句中方括号[]有啥用?

sql语句字符串的嵌套问题