本篇记录有关oracle数据库优化的部分内容。
1.建表字段类型
建表时如果字段用于存储数字,请使用number类型,不要使用varchar2和char,因为索引扫描时number的效率是它们的好几倍。
type number(19)
2.索引列值不为空
保证索引的字段都要有值,不要出现空值,可以给这个字段加个默认值,索引扫描时null值效率很低;
type number(19) default 1
3.联合索引顺序
关于联合索引,两个字段的索引可以不分先后,但是三个及三个以上时,请按照sql的字段顺序建立索引,正序反序都行:
select * from table where t1=1 and t2=2 and t3=3;
联合索引的顺序可为 t1,t2,t3 或 t3,t2,t1。
4.勿使用sql计算
在sql中尽量不要使用逻辑计算,尽量只查询数据,要将逻辑计算交给业务层去处理。
5.强制索引
有时sql不走索引而全表扫描,可以在让sql强制走索引,table:表名或表的别名,IDX:索引名
select /*+INDEX(table IDX)*/* from table
6.减少回表
查看执行计划时,如果出现TABLE ACCESS BY INDEX ROWID,说明回表了,当表数据达到千万级别时,回表造成的消耗是相当大的,下面说几个例子:
--索引为t1
select * from table where t1=1
查看执行计划时,这句肯定是回表了,当根据索引t1查询到数据时,会依据rowid重新查询一次数据,下面这句:
select t1 from table where t1=1
这条sql就不会回表查询,因为已经在索引列查询到了想要的数据,但是这条sql却毫无意义,一般情况下我们不太可能只要t1的数据,所以要建立联合索引:
--联合索引t1、t2、t3
select t2,t3 from table where t1=1
这条sql也不会造成回表,道理相同,已经在索引列查询到了想要的数据,但这时又出现了新的问题,如果查询的字段有十几个,那岂不是要建立十几个字段的联合索引,这显然不现实,这种情况下可以建立临时表查询:
with table_tmp as (select t2,t3,t4 from table where t1=1) select * from table_tmp tt where tt.t4=1
这条sql只会扫描一次原始表,当然也是回表了,但是相对而言回表的消耗会小很多,这也达到了优化的目的。简而言之,将所有的查询条件在临时表中查询出来,然后再对临时表进行查询操作,这对查询数量的sql格外有效。
7.直方图
做表分析,降低表的高水位,给表做直方图,需定期做,不然性能会越来越差。