首先对数据的优化不能仅仅盯着SQL语句,首先要解决的就是对数据库的设计,尽可能符合数据的三大范式再去考虑优化SQL语句。html
数据库的三大范式能够这样来简单理解:数据库
第1规范:没有重复的组或多值的列,这是数据库设计的最低要求。缓存
第2规范:每一个非关键字段必须依赖于主关键字,不能依赖于一个组合式主关键字的某些组成部分,消除部分依赖,大部分状况下,数据库设计都应该达到第二范式。oracle
第3规范:一个非关键字段不能依赖于另外一个非关键字段。消除传递依赖,达到第三范式应该是系统中大部分表的要求,除非一些特殊做用的表。数据库设计
一:SQL语句设计优化分布式
1.外键约束会影响插入和删除的性能,因此对一些表若是能够没有外键尽可能不要设置,若是对有些表中的数据有约束,最好在建表的SQL语句用描述完整性来实现,而不是用SQL程序中实现。性能
2.尽可能使用相同的或很是相似的SQL语句进行查询,这样不只充分利用SQL共享池中的已经分析的语法树,要查询的数据在SGA中命中的可能性也会大大增长。优化
3.SQL语句尽可能所有大写,特别是表名和列名,尤为是在使用SQL命令的缓存功能更加要统一大小写。由于oracle 老是先解析SQL语句,把小写的字母转换成大写的再执行。spa
4.根据缓存的特色,尽可能不要拼凑条件,而是使用占位符.net
5.避免不带任何条件的SQL语句的执行。没有任何条件的SQL语句在执行时,一般要进行FTS,数据库先定位一个数据块,而后按顺序依次查找其它数据,对于大型表这将是一个漫长的过程。
6.减小对数据库的查询次数,即减小对系统资源的请求,使用快照和显形图等分布式数据库对象能够减小对数据库的查询次数。
7.注意组合主键的字段次序,对于组合主键来讲,不一样的字段次序的主键的性能差异可能会很大,通常应该选择重复率低、单独或者组合查询可能性大的字段放在前面。
8.字段是数据库最基本的单位,其设计对性能的影响是很大的。
A、数据类型尽可能用数字型,数字型的比较比字符型的快不少。
B、数据类型尽可能小,这里的尽可能小是指在知足能够预见的将来需求的前提下的。
C、 尽可能不要容许NULL,除非必要,能够用NOT NULL+DEFAULT代替。
D、少用TEXT和IMAGE,二进制字段的读写是比较慢的,并且,读取的方法也很少,大部分状况下最好不用。
E、自增字段要慎用,不利于数据迁移。
9.索引
A、根据数据量决定哪些表须要增长索引,数据量小的能够只有主键。
B、根据使用频率决定哪些字段须要创建索引,选择常常做为链接条件、筛选条件、聚合查询、排序的字段做为索引的候选字段。
C、把常常一块儿出现的字段组合在一块儿,组成组合索引,组合索引的字段顺序与主键同样,也须要把最经常使用的字段放在前面,把重复率低的字段放在前面。
D、一个表不要加太多索引,由于索引影响插入和更新的速度。
10.建立视图
二:操做符优化
一、IN
用IN写出来的SQL的优势是比较容易写及清晰易懂,这比较适合现代软件开发的风格。可是用IN的SQL性能老是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有如下区别:
ORACLE试图将其转换成多个表的链接,若是转换不成功则先执行IN里面的子查询,再查询外层的表记录,若是转换成功则直接采用多个表的链接方式查询。因而可知用IN的SQL至少多了一个转换的过程。通常的SQL均可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。在业务密集的SQL当中尽可能不采用IN操做符。
优化SQL时,常常碰到使用IN的语句,必定要用exists把它给换掉,由于Oracle在处理In时是按Or的方式作的,即便使用了索引也会很慢。
二、NOT IN
强列推荐不使用的,由于它不能应用表的索引。用NOT EXISTS或(外链接+判断为空)方案代替
三、IS NULL或IS NOT NULL操做 也是尽可能避免
四、>及 <操做符(大于或小于操做符)
大于或小于操做符通常状况下是不用调整的,由于它有索引就会采用索引查找,但有的状况下能够对它进行优化,如一个表有100万记录,一个数值型字段 A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了,由于A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。
用>=替代>
高效:
SELECT …FROM DEPARTMENTWHERE DEPT_CODE >=0;
低效:
SELECT*FROM EMPWHERE DEPTNO>3
二者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录然后者将首先定位到DEPT NO=3的记录而且向前扫描到第一个DEPT大于3的记录.
五、LIKE操做符:尽可能使用 'aaa%' 而不是 '%aaa%'
六、用EXISTS替换DISTINCT:
七、用UNION替换OR (适用于索引列)
八、用IN来替换OR
九、当判断真假是,若是带and 或者 or :(当存在 “where 条件1 and 条件2” 时,数据库先执行右边的语句)
and尽可能把假的放到右边(一个为假就为假) Or尽可能把为真的放到右边(一个为真就为真)
十、应尽可能避免在 where 子句中对字段进行表达式操做,这将致使引擎放弃使用索引而进行全表扫描。 如:
SELECT * FROM T1 WHERE F1/2=100
应改成:
SELECT * FROM T1 WHERE F1=100*2