下面继续看查询的第二种情况,即包含表连接的情况:
? ? ? ?先创建表、约束、索引等准备工作
? ? ? ? ?创建了T表和T1表,默认情况下,HASH JOIN的效率要比NESTED LOOP高很多。如下所示:
? ? ? ? ?1.HASH JOIN
?? ? 22233次逻辑读。
? ? ?2.NESTED LOOP
? ? ? ?187164次逻辑读。
但是如果分页查询的内层是这种连接查询的话,使用NESTED LOOP可以更快的得到前N条记录。
下面看一下这种情况下的分页查询情况:
? ? ? ? 8次逻辑读。
? ? ? ?28次逻辑读。
看上去似乎HASH JOIN效率更高,难道上面说错了。
其实这个现象是由于这个例子的特殊性造成的。T表是根据DBA_USERS创建,这张表很小。
? ? ? ? HASH JOIN中第一步也就是第一张表的全表扫描是无法应用STOPKEY的,这就是上面提到的NESTED LOOP比HASH JOIN优势的地方。但是,这个例子中,恰好第一张表很小,对这张表的全扫描的代价极低,因此,显得HASH JOIN效率更高。但是,这不具备共性,如果两张表的大小相近,或者Oracle错误的选择了先扫描大表,则使用HASH JOIN的效率就会低得多。
? ? ? ?通过HINT提示,让Oracle先扫描大表,这回结果就很明显了。NESTED LOOP的效果要比HASH JOIN好得多。
下面,继续比较一下两个分页操作的写法,为了使结果更具有代表性,这里都采用了FIRST_ROWS提示,让Oracle采用NESTED LOOP的方式来进行表连接:
?? ? 28次逻辑读。
? ? ? 167372次逻辑读。
两种写法的效率差别极大。关键仍然是是否能将STOPKEY应用到最内层查询中。
对于表连接来说,在写分页查询的时候,可以考虑增加FIRST_ROWS提示,它有助于更快的将查询结果返回。
其实,不仅是表连接,对于所有的分页查询都可以加上FIRST_ROWS提示。不过需要注意的时,分页查询的目标是尽快的返回前N条记录,因此,无论是ROWNUM还是FIRST_ROWS机制都是提高前几页的查询速度,对于分页查询的最后几页,采用这些机制不但无法提高查询速度,反而会明显降低查询效率,对于这一点使用者应该做到心中有数。