sql优化

加快检索速度,降低增删改速度
在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
选择性高的列上创建索引
复合索引的主列应该是最有选择性的和where限定条件最常用的列。
一个索引是按f1,f2,f3的次序建立的,若where子句是f2 = :var2,则因为f2不是索引的第1个字段,无法使用该索引:
create index abc on student(sid,sname)
create index abc1 on student(sname,sid)
这两种索引方式是不一样的,索引abc对select * from student where sid=1;这样的查询语句更有效。
索引abc1对select * from student where sname=‘louis’这样的查询语句更有效。
因此建立索引的时候,字段的组合顺序是非常重要的,一般情况下,需要经常访问的字段放在组合字段的前面。
where子句中的字段参与计算,函数等,都会导致全表扫描。
索引和表单独存在。
创建索引的默认类型:b数索引
位图索引:(性别)create bitmap index student on(sex)
管理索引:合理的索引顺序。
t表(x,y,z),在x,y,z上分别都建立了索引(index1,index2,index3),那在查询select * from t where x=1 and y=2;的时候,会分别用到index1,index2.原理是先到index1索引表中查到符合x=1条件的记录,然后到index2索引表中查到y=2条件的记录。肯定是大于没有索引情况的全表扫描。
如果经常查询x=?和y=?,那推荐使用组合index(x,y),这种情况下组合索引的效率是远高于两个单独的索引的。同时在用组合索引的时候,大家一定要主要一个细节:建立组合索引index(x,y,z)的时候,那在查询条件中出现x,xy,xyz都是可以用到该组合索引,但是y,yz,z是不能用到该索引的。
删除一张表的重复记录(id是自增唯一主键,重复记录:其他字段都是一样):
delete from t where id not in(select min(id) from t group by name,age);效率低
delete from t al where not exists(select * from t a2 where al.id>a2.id and al.name=a2.name and a1.age = a2.age)效率高
不等于(<> !=),a<>0对它的处理只会产生全表扫描,改为a>0 or a<0
尽量不用通牌符“%”或者“_”作为查询字符串的第一个字符:当通配符"%"或者"_"作为查询字符串的第一个字符时,索引不会被使用。比如用T表中column1 like ‘%5400%’这个条件会产生全表扫描,如果改为column1 ‘X5400%’ or column1 like ‘B5400%’,则会利用column1的索引进行两个范围的查询。
where子句中避免在索引列上使用计算.
用">="代替">"
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的比率只为0.5%。

验证条件的执行顺序:
第1条语句执行不会出错,第2条语句会提示除数不能为零。
1.Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2;
2.Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1;
证明了SQL的语法分析是从右到左的。
把能使结果集最少的条件放在最右边。
Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。

统一SQL语句的写法
对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。
select * from dual
select * From dual
其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行!
用Where子句替换HAVING子句:避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。
on是最先执行,where次之,having最后。在多表联接查询时,on比where更早起作用。
用EXISTS替换DISTINCT:当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。
(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO (高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。
union all 和union
union和union all的区别是,union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。
用UNION-ALL 替换UNION ( 如果有可能的话):
or和in有时走索引,有时不走,效率差不多,少用
用UNION替换OR (适用于索引列):
用EXISTS替代IN、用NOT EXISTS替代NOT IN:
>用>=代替,<用<=代替,这样可以有效的利用索引。

原文地址:https://www.cnblogs.com/dapeng520/p/4543844.html