大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表扫描”效率要高的多。在编写SQL时,为了保证查询能够使用索引,需要避免出现如下场景:
在oracle中null是不能够作为索引的,如果某列数据中有“null”,不要在该列上创建索引,即使创建,也不会提高查询性能。
而在SQL语句中,如果使用is null和is not null,oracle的SQL优化器是不允许走索引的。
在使用like时,出现前导通配符,例如
此时,在targettable上的索引不会生效。
通配符包括'%'和'_'。
not会导致查询索引不生效。
not的形式有如下几种:
not (fee = 0)
fee <> 0
fee != 0
如果该字段上必须要使用索引,请修改为下列表达方式:
fee > 0 and fee < 0
在字段上使用表达式,会导致索引不生效。例如:
一般建议,将表达式放到=号右边,左边字段名称上不要添加任何表达式。例如:
在SQL语句中,常见的隐式转换如下:
字符型和数值型比较,Oracle会将字符型隐式转换成数值型;
字符型和date比较,oracle会将字符型隐式转换成date;
隐式转换如果发生在字段上,会造成索引失效。原理同“字段上加表达式”
在解释计划中,对于分区表的扫描,不可为“partition range all”。
where条件中,一定要加入对分区键列的条件过滤,同样要避免字段上加表达式和隐式转换
一般使用=判断,例如:
一般使用范围判断,例如between ... and ...或者>、<、>=、<=等
需要注意的原则与普通表上的索引一致。
在查询分区表时,Oracle先通过分区键找到需要查询的分区,在分区内部使用本地索引进行检索。
最常见的表连接方式,连接原理如下:
从外部表(驱动表)中获取第一条数据,去内部表中查询匹配,若匹配到则输出。
取第二条数据匹配,直到外部表数据遍历一遍。
在CBO下,Oracle自动选择数据量较小的表(或者子查询结果集)作为内部表。
在内部表上创建索引,提高每次检索的效率。
在绝大多数场景下,Hash Join是效率最高的连接。
一般用于大表和小表的连接,在小表数据能够全部放到内存中时,效率最高。
它的出现必然伴随着排序操作,效率较低,在Oracle 10g版本以后基本不会出现,若出现,需要确认是否在子查询中是否使用了不必要的排序。
这个就不用多说了,必须要避免的。
避免出现不必要的sort和sort group by,一般SQL中只在最终输出结果时进行排序,内部子查询不排序。