当数据量小的时候,SQL优化或许可有可无,可是当数据量达到必定量级以后,性能优化将变得相当重要,甚至决定系统成败。数据库
临时表性能优化
在临时表指定字段建立索引。函数
删除重复记录性能
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHEREX.EMP_NO = E.EMP_NO);
用Where子句替换HAVING 子句优化
避免使用 HAVING 子句, HAVING 只会在检索出全部记录以后才对结果集进行过滤.spa
用UNION替换OR或者INcode
(适用于索引列)一般状况下,用UNION 替换WHERE 子句中的OR将会起到较好的效果. 对索引列使用OR 将形成全表扫描.blog
区分in和exist索引
select * from 表A where id in (select id from 表B)
这句至关于进程
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
若是是exists,那么之外层表为驱动表,先被访问,若是是IN,那么先执行子查询。
因此IN适合于外表大而内表小的状况;EXISTS适合于外表小而内表大的状况
缘由:结果不许确,查询性能低下
建议:在写查询时,尽可能避免使用Not In,而转换为本文提供的Not Exists等价形式,将会减小不少麻烦。
SQL with(unlock)与with(readpast)
全部Select加With(NoLock)解决阻塞死锁,在查询语句中使用NOLOCK和READPAST,处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST 。
对于非银行等严格要求事务的行业,搜索记录中出现或者不出现某条记录,都是在可容忍范围内,因此碰到死锁,应该首先考虑,咱们业务逻辑是否能容忍出现或者不出现某些记录,而不是寻求对双方都加锁条件下如何解锁的问题。 NOLOCK 和 READPAST 都是处理查询、插入、删除等操做时候,如何应对锁住的数据记录。可是这时候必定要注意NOLOCK 和 READPAST的局限性,确认你的业务逻辑能够容忍这些记录的出现或者不出现, 简单来讲:
NOLOCK 可能把没有提交事务的数据也显示出来。
READPAST 会把被锁住的行不显示出来。
不使用NOLOCK和READPAST,在Select操做时候则有可能报错误:事务(进程 ID **)与另外一个进程被死锁在锁资源上,而且已被选做死锁牺牲品。
建立索引的的字段尽可能小,最好是数值,好比整形int等;
对于频繁修改的字段,尽可能不要建立索引,维护索引的成本很高,并且更容易产生索引碎片;
按期的索引维护,如索引碎片的修复等;
不要创建或维护没必要要的重复索引,会增长修改数据(新增、修改、删除数据)的成本;
使用惟一性高的字段建立索引,切不可在性别这样的低惟一性的字段上建立索引;
在SQL语句中,尽可能不要在Where条件中使用函数、运算符或表达式计算,会形成索引没法正常使用;
应尽可能避免在 where 子句中对字段进行 null 值判断,不然将致使引擎放弃使用索引而进行全表扫描;
应尽可能避免在 where 子句中使用!=或<>操做符,不然将致使引擎放弃使用索引而进行全表扫描;