如果要详细的描述Oracle的prefetching工作机制是十分困难的。因为Oracle的Prefetching是和优化器与SQL执行紧密相关的。Oracle的优化器与SQL执行器十分强大,远远超过其他所有的数据库,这也是ORACLE数据库性能强大的最主要的原因之一。Oracle通过SQL的执行计划来十分精确的的确定是否使用prefetching功能。一个已知的大概率启用prefetching的场景是nested loop是与排序(sort),位图扫描(bitmap scan)与部分nested loop 连接产生的row source进行连接时,Oracle会根据row source的实际情况,在table access by index rowid的时候自动启用prefetching,从而提高这一步操作的性能。比如下面的执行计划:
这个执行计划中的,destination上的TABLE ACCESS BY INDEX ROWID就会启用prefetching。根据Oracle的版本不同,启用prefetching的规则与场景会有很大的不同,因为Oracle的优化器的发展是十分迅速的。Oracle的这种基于优化器与执行器的预读机制,比OS或者设备驱动中的哪种傻瓜式的预读机制,那是要强上无数倍了。这种预读机制是基于数据与业务逻辑的,其准确性与效率十分高。而OS层面或者设备驱动层面的PRE-READ机制大多数是根据简单的算法,这种算法没有业务逻辑,也不知道应用读取数据的实际需求,所以效率就肯定远远低于Oracle了。因此在使用Oracle数据库的时候,特别是以OLTP为主的系统上,Oracle不建议OS启用PRE-READ机制,因为Oracle的PREFETCHING效率更高。而对于一些没有如此强大的数据库,使用OS提供的PRE-READ机制,还是能够起到一定的提高IO性能,从而提升数据库处理能力的效果的。不过也要注意,对于一个OLTP系统,如果IO延时过高了,或者IO负载过高,那么加大PRE-READ可能会导致更差的运行效率,这时候减少PRE-READ的大小可能反而会提高性能。总之PRE-READ的调整必须十分贴合场景,只有Oracle的与优化器和执行器紧密相关的算法,才真正的是高效的算法。在运维领域有一句话,通用的另外一个含义就是低效,在这里很好的解释了Oracle的prefetching与OS的PRE-READ之间的差距。