我有一个表order
,非常简单,它存储order
数据。
我有一个view
,它存储货币对和货币汇率。视图创建如下:
create or replace view view_currency_rate as (
select c.* from currency_rate c, (
select curr_from, curr_to, max(rate_date) max_rate_date from currency_rate
where system_rate > 0
group by curr_from, curr_to) r
where c.curr_from = r.curr_from
and c.curr_to = r.curr_to
and c.rate_date = r.max_rate_date
and c.system_rate > 0
);
这里没什么特别的,这个view
填充currency_rate
表中的最新货币汇率(curr_from - > curr_to)。
当我执行以下操作时,它会填充80k行(所有数据),因为我在订单表中有大量记录。花费的时间不到5秒。
首次查询:
select * from
VIEW_CURRENCY_RATE c, order a
where
c.curr_from = A.CURRENCY;
我想添加更多过滤器,所以我认为它可能更快,所以我添加了这个:
第二次查询:
select * from
VIEW_CURRENCY_RATE c, order a
where
a.id = 'xxxx'
and c.curr_from = A.CURRENCY;
现在它运行超过1分钟!我完全不知道发生了什么。我以为这会是一些oracle优化器出错了,所以我试着找另一种方式,想想80K数据可以很快填充,所以我尝试从中获取数据,所以我将SQL嵌套如下: / p>
select * from (
select * from
VIEW_CURRENCY_RATE c, order a
where
c.curr_from = A.CURRENCY
)
where id = 'xxxx';
它也很慢!我没想到,有人可以解释我的剧本会发生什么吗?
2016年9月6日更新
在我知道如何“解释计划”之后,我抓住了屏幕:
拳头查询(快速查询80K数据):
第二个查询(慢一个):
缓慢的一个完全破坏视图并形成一个新的SQL!这非常奇怪,Oracle如何像这样优化它?
答案 0 :(得分:0)
似乎问题与第二次查询的计划有关。因为它使用嵌套循环来代替散列连接。 首先检查_hash_join_enable是否为真,如果它不是真的将其改为真。如果确实如此,那么oracle优化器存在一些问题。用于测试它使用USE_HASH(tab2 tab1)提示。
此致 穆赫辛
答案 1 :(得分:0)
我正在使用Mike解决方案,我重新编写脚本,并且它现在正在快速运行,虽然根本原因尚未确定,可能是由于oracle优化器算法以我期望的不同方式工作。