一、IN 操做符 程序员
用IN写出来的SQL的优势是比较容易写及清晰易懂,这比较适合现代软件开发的风格。可是用IN的SQL性能老是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有如下区别:sql
ORACLE试图将其转换成多个表的链接,若是转换不成功则先执行IN里面的子查询,再查询外层的表记录,若是转换成功则直接采用多个表的链接方式查询。因而可知用IN的SQL至少多了一个转换的过程。通常的SQL均可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。性能
推荐方案:在业务密集的SQL当中尽可能不采用IN操做符,用EXISTS 方案代替。测试
Exists只检查存在性,性能比in强不少,有些朋友不会用Exists,就举个例子
例,想要获得有电话号码的人的基本信息,table2有冗余信息
select * from table1;--(id,name,age)
select * from table2;--(id,phone)
in:
select * from table1 t1 where t1.id in (select t2.id from table2 t2 where t1.id=t2.id);
Exists:
select * from table1 t1 where Exists (select 1 from table2 t2 where t1.id=t2.id); 大数据
二、NOT IN操做符 spa
此操做是强列不推荐使用的,由于它不能应用表的索引。 索引
推荐方案:用NOT EXISTS 方案代替 内存
三、IS NULL 或IS NOT NULL操做(判断字段是否为空) 资源
判断字段是否为空通常是不会应用索引的,由于索引是不索引空值的。
开发
推荐方案:用其它相同功能的操做运算代替,如:age is not null 改成 age>0 或age>’’等。不容许字段为空,而用一个缺省值代替空值,如申请中状态字段不容许为空,缺省为申请。
四、LIKE操做符
LIKE操做符能够应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,可是若是用得很差则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。
一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,若是改为YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能确定大大提升。
五、同一功能同一性能不一样写法SQL的影响。
如一个SQL在A程序员写的为 Select * from zl_yhjbqk
B程序员写的为 Select * from dlyx.zl_yhjbqk(带表全部者的前缀)
C程序员写的为 Select * from DLYX.ZLYHJBQK(大写表名)
D程序员写的为 Select * from DLYX.ZLYHJBQK(中间多了空格)
以上四个SQL在ORACLE分析整理以后产生的结果及执行的时间是同样的,可是从ORACLE共享内存SGA的原理,能够得出ORACLE对每一个SQL 都会对其进行一次分析,而且占用共享内存,若是将SQL的字符串及格式写得彻底相同,则ORACLE只会分析一次,共享内存也只会留下一次的分析结果,这不只能够减小分析SQL的时间,并且能够减小共享内存重复的信息,ORACLE也能够准确统计SQL的执行频率。
六、WHERE后面的条件顺序影响
WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响。如:
Select * from zl_yhjbqk where dy_dj = '1KV如下' and xh_bz=1
Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV如下'
以上两个SQL中dy_dj(电压等级)及xh_bz(销户标志)两个字段都没进行索引,因此执行的时候都是全表扫描,第一条SQL的dy_dj = '1KV如下'条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此能够得出第二条SQL的CPU占用率明显比第一条低。
七、查询表顺序的影响
在FROM后面的表中的列表顺序会对SQL执行性能影响,在没有索引及ORACLE没有对表进行统计分析的状况下,ORACLE会按表出现的顺序进行连接,因而可知表的顺序不对时会产生十分耗服物器资源的数据交叉。(注:若是对表进行了统计分析,ORACLE会自动先进小表的连接,再进行大表的连接)
八、分页查询
通常的分页sql以下所示:
sql1:select * from (select t.*,rownum rn from XXX t)where rn>0 and rn <10;
sql2:select * from (select t.*,rownum rn from XXX t where rownum <10)where rn>0;
乍看一下没什么区别,实际上区别很大...125万条数据测试,
sql1平均须要1.25秒(咋这么准呢? )
sql2平均须要... 0.07秒
缘由在于,子查询中,sql2排除了10之外的全部数据
固然了,若是查询最后10条,那效率是同样的
八、能用一句SQL,千万别用2句SQL