SQL语句优化总结[1].doc
文本预览下载声明
数据库优化总结
一、 前言 1
二、 在SELECT子句中避免使用‘*’ 1
三、 删除重复记录 1
四、 计算记录条数 2
五、 减少对表的查询 2
六、 EXISTS 与IN使用 2
七、 使用索引 3
八、 UNION与UNION ALL的使用 4
九、 驱动表的选择 5
十、 Where语句中条件的顺序 5
十一、 使用where代替having语句 5
十二、 使用表的别名 5
十三、 表记录删除 6
十四、 Decode函数使用 6
十五、 尽量少用子查询 6
十六、 SQL语句拆分 6
十七、 SQL语句中参数的使用 7
十八、 解释计划 7
前言
下面是对使用ORACLE的SQL语句的一些优化总结,借鉴了一些资料和自己的经验总结,只是部分优化方法,甚至可能还会有不准确的地方,希望看官给予补充我修正,以提高大家写SQL语句的水平。
在SELECT子句中避免使用‘*’
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.
删除重复记录
最高效的删除重复记录方法 ( 因为使用了ROWID)
DELETE FROM EMP E
WHERE E.ROWID (SELECT MIN(X.ROWID)
FROM EMP X
WHERE X.EMP_NO = E.EMP_NO)
Oracle的ORWID用来唯一标识表中的一条记录,是这条数据在数据库中存放的物理地址Select * from clmb01c
Where cjxsdm = (select max(cjxsdm) from clmb10)
And csqdh = (select min(csqdh) from clmb10)
Where id = 833997
可改成
Select * from clmb01c
Where (cjxsdm, csqdh)= (select max(cjxsdm),min(csqdh) from clmb10) where id = 833997;
更新也一样
Update clmb01c set (cjxsdm,csqdh) = (select max(cjxsdm),min(csqdh) from clmb10)
Where id = 833997;
当然此例还有其它写法,在此拿出只是说明观点
例2:
Update clmb01c set cdjzt = ‘1’ where id = 833997;
Select nhjje into n_hjje from clmb01c where id = 833997;
以上两语句可合成一个
Update clmb01c set cdjzt = ‘1’ where id = 833997 returning nhjje into n_hjje;
EXISTS 与IN使用
对于这两个操作符,通常认为EXISTS会比IN效率高,特别是EXISTS的子查询语句可用到索引时会比IN效率高
Oracle在处理这两个操作时处理如下:
IN:Oracle将IN后面的子查询语句调入到内存,然后排序,如果记录多会非常占用系统资源
EXISTS:在每次查询时调用一次子查询语句,所以就要保证子查询语句能使用索引,否则就会全表扫描,如果记录数很多那是很可怕的事情,会产生迪卡尔乘积
结论:记录小的时候用哪个都对效率没有多大影响,对于记录大时一定要使用EXISTS,并保存子查询使用索引
对于NOT EXISTS和NOT IN一定要选用NOT EXISTS,还可使用(外连接+判断为空)
使用索引
对于数据量大的表一定要建立适当的索引,正确的使用索引可以级大的提高数据检索效率,在写SQL语句时要考虑表索引的使用,但索引的缺点一是增加物理空间的占用,二是对表的增、删、改会增加一次索引的增、删、改操作,所以对于大表要建立并使用索引,但不能过多
使用索引要注意以下几点:
要按索引列构造SQL语句的where条件才能使用到索引
使用不等于操作符则不能使用索引
例:select col1,col2 from table1 where col1 ‘AA’
如果列col1是索引则此写法不能使用索引,同样还有not in (‘AA’)
那出现这种问题如何解决呢?
那就要改变这种写法,比如判断的条件值有‘AA’,‘BB’,‘CC’
则条件改写成col1 = ‘BB’ or col1 = ‘CC’
使用is NULL 则不能使用索引
如
显示全部