以下优化都是建立在表数据比较多的情况下,并且有建立索引(下面说的都是围绕索引来说事)
- 避免多表查询中连接条件不充分
如:表card上7000+行数据,在card_no上有索引 , account表有20W+数据 , 在account_no上有索引 , 看如下两个sql:
-- 20秒
select sum(a.amount) from account a, card b where a.card_no = b.card_no
-- < 5秒
select sum(a.amount) from account a, card b where a.card_no = b.card_no and a.account_no = b.account_no
- 避免在索引列上使用任何函数、运算等操作
当在索引列上使用函数、运算操作时,oracle是全表扫描而不是索引扫描
- 函数索引
是Oracle 8i +带来的产物, 如果在name字段上建有索引 ,但是在使用时where条件经常会substr(name,x,x),此是不会使用索引扫描而是使用全表扫描 , 此时就可以建立函数索引
select * from A where subtr(name,2,4) ;
-- 建立函数索引
create index 索引名 on 表名(subtr(name)) ;
-
SQL语句中,只要where子句使用了is null或is not null ,语句执行时不会使用索引扫描
-
通配符(%)的like语句
如果某字段有索引 ,但是在where子句中使用like并且是%开头 ,执行时则不会进行索引扫描
-- 不会索引扫描
select * from A where name like '%a%' ;
-- 会索引扫描,因为%没有在开头
select * from A where name like 'a%' ;
-
减少使用not <>或!= , 因为是全表扫描而不会走索引扫描(在有索引的情况)
-
使用union替换or (适用于索引列且数据量较大时)
-- 低效 ( or不会走索引扫描)
select name from A where age = 10 or name like 'a%';
-- 高效 (前提是age和name建立了索引)
select name from A where age = 10
union
select name from name like 'a%' ;
- 使用 >= 替换 >
-- 下面两个语句的执行结果是一样的
-- 高效
select name from A where id >= 3 ;
-- 低效
select name from A where id > 2 ;
-- 两都区别:前者执行时会直接跳转到id等于3的记录而后者会先定位到id等于2的记录并向前扫描第一个id的大于2的记录
-
尽量使用表连接代替exists、in
-
group by , order by 尽量写到SQL的最后
网友评论