之前总结了部分使用索引的规则,其中有一条: 小表不必要加索引
今个,在读Oracle性能诊断艺术的时候,作者对这条规则提出了异议,说是曾经在一次调优中,对一个小表添加索引,使得整个查询的性能得以提高30倍。
我觉得非常诧异,再细读下去才得知,小表做一次全表扫描,和做一次索引定位,时间的相差也许只有0.01秒,一般情况下是可以忽略不计的, 但小表如果在查询中处于核心路径的话,对小表的访问次数可能会放大很多倍,如果放大10000倍,那就相差100秒,这样的消耗还是相当严重的。
为此,特意准备了一组数据进行测试,目前开发的项目中正好有这样的大小表,可以测:
placement 20w行左右, schverfile 100行
select p.trafficId from placement p where exists (select null from schverfile s where p.schedFileName = s.schedFileName)
采用子关联查询,分别在schverfile.schedFileName有索引和无索引的条件下跑, 前者是0.91秒,后者确有27.37秒。 对于每一行p的记录,都会调用一次s的查询,相当于放大了20W倍
所以,得出结论是,小表是否加索引,还得看其运行的查询,处于核心路径的小表,如果不会频繁修改,最好是加上索引,以防万一。 如果是频繁修改的,那就还得在权衡维护索引的消耗和全表扫描消耗之间做一个权衡了。
今个,在读Oracle性能诊断艺术的时候,作者对这条规则提出了异议,说是曾经在一次调优中,对一个小表添加索引,使得整个查询的性能得以提高30倍。
我觉得非常诧异,再细读下去才得知,小表做一次全表扫描,和做一次索引定位,时间的相差也许只有0.01秒,一般情况下是可以忽略不计的, 但小表如果在查询中处于核心路径的话,对小表的访问次数可能会放大很多倍,如果放大10000倍,那就相差100秒,这样的消耗还是相当严重的。
为此,特意准备了一组数据进行测试,目前开发的项目中正好有这样的大小表,可以测:
placement 20w行左右, schverfile 100行
select p.trafficId from placement p where exists (select null from schverfile s where p.schedFileName = s.schedFileName)
采用子关联查询,分别在schverfile.schedFileName有索引和无索引的条件下跑, 前者是0.91秒,后者确有27.37秒。 对于每一行p的记录,都会调用一次s的查询,相当于放大了20W倍
所以,得出结论是,小表是否加索引,还得看其运行的查询,处于核心路径的小表,如果不会频繁修改,最好是加上索引,以防万一。 如果是频繁修改的,那就还得在权衡维护索引的消耗和全表扫描消耗之间做一个权衡了。