Oracle表连接方法(上)
Oracle表连接方法。
一、 排序合并连接:Sort Merge Join
两张表在做表连接时用排序和合并操作来得到结果。
假设这两张表:T1和T2 ,它们进行排序合并连接操作的步骤如下:
1、首先用目标SQL中指定的谓词去访问表T1,然后对结果按照表T1的连接列来排序,排序好的结果集,记为结果集1。
2、再继续用目标SQL中指定的谓词去访问表T2,然后对结果按照表T2的连接列进行排序,排序好的结果集,记为结果集2 。
3、接下来进行合并:
遍历结果集1,取出结果集1中的第一条记录,然后去结果集2中遍历,按照条件判断是否存在这条记录。然后取结果集1的第二天记录,去结果集2中进行遍历,直到所有的数据都遍历完成。但是因为结果1和结果2集都是排序好的结果集,所以并不会每次都对结果集2进行全部遍历。
排序合并连接的优缺点及适用场景:
1 通常情况下,排序合并连接的效率远不如哈希连接,但前者使用范围更广,因为哈希连接值适用于等值连接。而排序合并连接还能英语其他连接条件。
2 严格意义上,排序合并连接并不存在驱动表的概念。
3 排序合并连接不适用与OLTP系统。OLTP系统排序是非常昂贵的操作。
二、 嵌套循环连接: Nested Loops Join
两张表在做表连接时依靠两层嵌套循环(分别为外层循环和内层循环)来得到连接结果集的表连接方法。
两张表T1和T2 在做表连接使用的嵌套循环连接时,Oracle执行的步骤如下;
1 首先,优化器会按照一定的规则来决定表T1和T2谁作为驱动表和被驱动表。驱动表用于外层循环,被驱动表用于内层循环。假设驱动表是T1 被驱动表是T2
2 接着用目标SQL中指定的谓词条件去访问驱动表T1,访问驱动表T1后得到的结果集记为驱动结果集1。
3 然后遍历驱动结果集1并同时遍历T2,这个类似于双层循环的操作,不在赘述。
关于嵌套循环连接的优缺点及适用场景,总结如下:
1 如果驱动表所对应的驱动结果集的记录数比较少,同时在被驱动表的连接列上又存在唯一性的索引,那么此时使用嵌套循环连接的执行效率救护非常高。但如果驱动表所对应的驱动结果集的记录数很多,即便在被驱动表的连接列上存在索引,此时使用嵌套循环连接的执行效率也不会高。
2
只要驱动结果集的记录数少,就具备了做嵌套循环连接的前提条件,驱动结果集是驱动表应用了目前sql中指定的谓词后得到的结果集,因此大表也可以做驱动表,只要目标sql中指定的谓词可以将驱动结果集的数量降下来。
3
嵌套循环连接还有一个优点就是,嵌套循环可以实现快速响应。 即它可以在第一时间先返回已经连接过且满足连接条件的记录,而不必等所有的连接操作操作完成之后才返回结果。
虽然排序合并和哈希连接也可以第一时间返回满足连接条件的记录,但是,排序合并连接首先要做的是排序操作,也就是返回结果时,一定是在排序操作完成之后。哈希连接也要等hashTable建立完成之后,才会返回结果。
如果Oracle使用的是嵌套循环连接,且在被驱动表的连接列上存在索引,那么Oracle在访问该索引时,通常会使用单块读,这意味这嵌套循环连接的驱动结果集有多少记录,Oracle就需要访问索引多少次,另外如果目标sql中查询的列并不能全部从被驱动表的相关索引中获得,那么Oracle在做完嵌套循环连接后就还需要对被驱动表进行回表操作,这个回表操作也使用单块读,这意味着做完嵌套循环连接后的连接结果集有多少条记录,Oracle就需要回表多少次。
对于单块读,Oracle需要耗费物理IO去相应的数据文件中获取。这样显然会直接影响单块读的执行效率。
为了提高执行效率Oracle11g 引入了向量IO(Vector I/O) ,在引入向量IO后,Oracle就可以将原先一批单块读所需要耗费的物理IO组合起来,然后用一个向量IO去批量处理他们。
不过这样,嵌套循环就不能快速相应了,显然是在所有的连接操作执行完成之后,才会返回结果集。