可以看到进行了笛卡尔集,再HASH JION的时候使用了过多的临时表空间用于存储HASH值,达到了2.6M。
而笛卡尔集是test1和test2做的。其实我们是有连接条件的,连接条件是
filter("A"."test"="B"."test" AND "A"."test1" I
OR "A"."test2"="B"."test3")
但是优化器没有这样使用,而是先做了笛卡尔集然后再做了HASH JION然后把连接条件做为了过滤条件。
所以解决问题的关键在于让优化器先做连接条件再HASH JION。
所以我改写了以上片段如下:
其实就是用use_concat提示来告诉执行计划用UNION ALL的方式来代替OR
(
USE_CONCAT
The USE_CONCAT hint forces combined OR conditions in the WHERE clause of a query to be transformed into a compound query using the UNION ALL set operator. Generally, this transformation occurs only if the cost of the query using the concatenations is cheaper than the cost without them.
The USE_CONCAT hint disables IN-list processing and OR-expands all disjunctions, including IN-lists.
)
最后修改完的语句如下,这个语句运行时间不到3秒。
SELECT *
FROM (SELECT row_.*, rownum rownum_
FROM (select *
from (select /*+ use_concat */ a.payrefdate,
..................
union all
..............
union all
............)
WHERE rownum_ > 0;
现在非常快了。