高效sql的注意事项

1.
只返回需要的列,避免用select * from t1
2.
加过滤条件限制返回的行数: select name, dep_name from t1 where age>30
3.
避免笛卡尔乘积,select * from a,b
--使用参数化查询,where col1=?,减少编译时间
4.
避免对查询条件计算,where salary*2>xx 改为salary > xx/2

5.
尽量避免在索引列上使用not,!=和<>,索引只能告诉什么在表中,而不能告诉什么不在表中,
当数据库遇上以上几种符号时,将不再使用索引,使用全表扫描
6.
in/exist, not in/not exist
可以用exists代替in,可以提高查询的效率.其实也是分情况的:       
in与exists的使用取决于子查询集合大小,IN适合于外表大而内表小的情况;
EXISTS适合于外表小而内表大的情况(前提是内表字段有索引).
所以结论: 如果子查询得出的结果集记录较少,外层主查询中的表较大且又有索引时应该用in,
反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
举例,以下两个sql是高效的:
select * from big_tab where id in (select id from small_tab);     --内表small_tab是小表,而外表big_tab是大表且有索引
select * from small_tab a where exists(select 1 from  big_tab b where b.id = s.id); --内表big_tab是大表且有索引,而外表small_tab是小表

原因: in 是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
      一直以来认为exists比in效率高的说法是不准确的。

7.
无论任何情况: not exists > not in;
原因:   
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

8.
如果可能,尽量避免使用order by和distinct等排序操作

9.
任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

10.
注意LIKE模糊查询的使用,避免%%。

--使用for read only或for fetch only

11.
避免数字类型转换, 避免数据类型不匹配


--减少数据库访问次数

12.
注意SQL的where条件书写顺序:
对于大部分数据库而言,sql语句的解析都是有顺序的
比如Oracle数据库采用自下而上的顺序解析where字句,所以那些可以滤过大量纪录的条件应该写在where字句的末尾,例如:
(DB2就不需要,因为DB2的优化器足够智能,能够根据实际情况来对sql进行优化来决定合理的执行顺序)
select * from table e
      where  25<(select count(*)
                          from table
                          where count=e.count);    
                   and  h>500
                   and d='001';
说明: d='001'能够过滤掉绝大多数数据,所以这样写更高效

--避免使用HAVING字句

12.
尽量多使用commit

13.
有条件的使用union-all代替union提高效率

14.
用UNION替换OR (适用于索引列) , 如:
select dep_name, emp_name from tab1 where age>34 or gdp<'C';
如果age和gdp都是索引列,那么可以用union更高效:
select dep_name, emp_name from tab1 where age>34
union
select dep_name, emp_name from tab1 where gdp<'C';

15.
用>=替代>

高效:
SELECT * FROM  EMP  WHERE  DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3

两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。

猜你喜欢

转载自blog.csdn.net/liujinwei2005/article/details/79364591