首页 > 技术文章 > ORACLE SQL优化

yanyan-rourou 2021-05-12 22:49 原文

使用索引避免全表扫描:
  1,在where列和order by列上建立索引,当order by时,必须将列设置为NOT NULL,否则不走索引,order by 多个列时,需要设置复合索引并且order by的顺序必须和复合索引的顺序相同
  2,不要对where子句进行null值判断,否则放弃索引全表扫描,可以使用函数索引:例如表名(nvl(列名, '0')),使用的时候就是nvl(列名, '0')
  3,尽量避免在where子句上使用 !=,否则放弃索引全表扫描,解决办法,强制使用索引,在SELECT 字段位置使用 /*+INDEX(表名 索引名)*/* 强制开启索引,当不等于数字时,可以使用or >和 or<来替换不等于
  4,尽量避免在where子句中使用 or连接条件,只要有字段没有索引,将会导致放弃索引全表扫描,建议使用 union/union all 连接,这样就不会全局影响有索引的查询了
  5,慎用 in 和not in:
    情况1:IN(值列表):当字段值可选性(重复的多,可选性少)比较少时,IN(值列表)也是不会走索引的
    情况2:IN (子查询):当子查询与主查询关联(子查询索引字段与主查询关联)时,子查询还是会走索引的
    NOT IN 和NOT EXISTS主表都不会走索引的,NOT IN 时当子查询与主查询关联(子查询索引字段与主查询关联)时,子查询还是会走索引的
  6,慎用模糊查询,前模糊匹配查询会全表扫描,例如:like '%xxx' 和 like '%xxx%',解决办法:强制使用索引,使用/*+INDEX(表名 索引名)*/* 强制开启索引
  7,避免在where子句对索引字段进行表达式操作,例如: WHERE NUM/2 = 10,可以修改为 WHERE NUM= 10*2
  8,避免在where子句中对索引字段进行函数运算,例如: where to_number('123') = '123',将会放弃索引全表扫描,可以使用函数索引例如:CREATE INDEX 索引名 ON 表名(TO_NUMBER(列名))
  9,使用复合索引要注意前缀性可选性,前缀性:比如建立了复合索引 A,B,C, 只有当where条件包含A才会走索引,可选性:可选性高的字段排在前面,比如 A 字段作为where过滤条件,A字段有1,2,3,4,5,6,7,8,9,10 一共10个值,B字段一共有1,1,1,1,1,2,2,2,2,2 此时A字段选择性高(有10种不同的选择),选择性越高,过滤掉的结果越多,速度也就越快

  10,避免索引字段隐式转换,比如数据库中使用的是字符串类型的数字,和数字类型进行比较,会转换成为 TO_NUMBER(字段) = 数值,在索引字段使用了函数导致放弃索引

 

  未完待续。。。。。如果有问题请指出!谢谢!

推荐阅读