Sunday, January 3, 2016

How to think in SQL

1. 不要在字段上用转换函数,尽量在常量上用。如:
  select id from employee where to_char(create_date,'yyyy-mm-dd')='2012-10-31'  (错)
  select id from employee where create_date=to_date('2012-10-31','yyyy-mm-dd')   (对)
2. 不论一个sql中涉及到多个表,每次都用两个表(结果集)操作,得到新的结果后,再和下一个表(结果集)操作。
3. 尽量使用exists而非in
 当然这个也要根据记录的情况来定用exists还是用in, 通常的情况是用exists
 select id from employee where salary in (select salary from emp_level where....)   (错)
 select id from employee where salary exists(select 'X' from emp_level where ....)   (对)
4. 使用not exists 而非not in
    和上面的类似
5. 正确使用索引
  索引可以提高速度,一般来说,选择度越高,索引的效率越高
6.. 索引类型
  唯一索引,对于查询用到的字段,尽可能使用唯一索引。
  还有一些其他类型,如位图索引,在性别字段,只有男女的字段上用。
7. 在经常进行连接,但是没有指定为外键的列上建立索引
8. 在频繁进行排序会分组的列上建立索引,如经常做group by 或 order by 操作的字段。
9. 在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不建立索引。如性别列上只有男,女两个不同的值,就没必要建立索引(或建立位图索引)。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。
10.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
  select id from t where num=10 or num=20
  可以这样查询:
  select id from t where num=10
  union all
  select id from t where num=20
11.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

12.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
  select id from t where num/2=100
  应改为:
  select id from t where num=100*2
13.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
  select id from t where substring(name,1,3)='abc'--name以abc开头的id
  select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
  应改为:
  select id from t where name like 'abc%'
  select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
14.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
15. SQL语句看起来就一条,但是相对于Java、C等编程语言来说,学习起来难度要大很多。主要是SQL这玩意太抽象了。一条编程语言语句,我们能清楚地知道执行结果是什么;而一条SELECT语句,得到最终结果可能要经历好几个步骤,脑袋要转好几个弯。
16. 建立一个临时表 多种数据类型的字段可以都加上一些 然后练习如何在这些数据里查询和准确定位到自己想要的语句,在练习的过程当中 你就会自然而然的想去使用和找寻相关的函数和方法 这个时候你就可能会理解 什么时候要用JOIN 什么时候要用LEFT JOIN 什么时候需要GROUP BY一下

No comments:

Post a Comment