oracle复合索引介绍(多字段索引) : http://ysj5125094.iteye.com/blog/1745367
(1).门牌号码:ROWID
欲介绍索引,先介绍一个概念:ROWID.在数据库中,每条记录都有自己的物理地址,叫做ROWID,包括所属的数据文件号,数据块号,以及在该数据块中的具体位置信息等.ROWID就相当于一个门牌号码,也相当于一本书的页码.
(2).索引就是目录:
索引就是一本书的目录.索引包括被索引的字段值和所对应的ROWID,分别相当于目录中的书条目和对应的页码.
20/80规则: 80%的性能问题可以由20%的优化技术所解决.
错误的SQL语句会导致索引的不执行.如下:
to_char(DJ_SZ.JDRQ,'yyyy-mm-dd') between '2012-04-01' and '2012-04-17' -- 即便在DJ_SZ.JDRQ字段建立了索引,该索引仍然无法启动,依然是全表扫描.因为索引树中记录的是DJ_SZ.JDRQ字段值,而不是to_char(DJ_SZ.JDRQ,'yyyy-mm-dd')数值.因此DJ_SZ.JDRQ索引无法使用.上述语句片段应该修改成: DJ_SZ.JDRQ between to_date('2012-04-01','yyyy-mm-dd') and to_date('2012-04-17','yyyy-mm-dd')
开发规范之一 : 不要轻易在字段前增加函数.
-- oracle其实挺笨的,如果这样写: DJ_NSRZT_BG.YXQ_Z + 7 < sysdate -- oracle 也不会启动YXQ_Z字段上的索引,必须修改成这样: DJ_NSRZT_BG.YXQ_Z < sysdate - 7 -- 原因同上
开发规范之二 : 尽量不要将字段嵌入表达式之中.
针对前面问题,为什么不可以直接使用oracle函数索引呢?例如:
create index idx_1 on DZ_SJ(to_char(JDRQ,'yyyy-mm-dd'));
的确,只要数据库运行在基于成本的优化器(CBO)模式下,并且将参数query_rewrite_enabled设置为true,就可以启动函数索引.而且不需要进行复杂的语句转换,提高语句的可读性.但本人建议,尽量少使用函数索引,而将函数进行转换.原因如下:
(1).函数索引是需要维护的.当数据库每次进行该表的DML操作时,oracle都需要维护函数索引,也就是说需要进行一次计算,维护成本将高于普通索引.
(2).函数索引的计算值可能大于原字段值,将消耗更多的索引存储空间.