我在Oracle中使用查询遇到了一个非常奇怪的行为。查询本身非常庞大且相当复杂......但每次运行它时基本相同。但是,在返回较小的结果集时,它似乎执行得更慢。我能给出的最好的例子是,如果我在其上设置此过滤器,
and mgz_query.IsQueryStatus(10001,lqo.query_id)>0
返回12,429条记录中的960条,我看到执行时间约为1.9秒。但是,如果我将过滤器更改为
and mgz_query.IsQueryStatus(10005,lqo.query_id)>0
返回12,429条记录中的65条,我看到执行时间约为6.8秒。当深入挖掘时,我发现较小的结果集似乎比较大的结果集执行了更多的缓冲区获取。这对我来说似乎完全违反直觉。
正在运行的查询大约需要8000个字符(除非有人想要它,我不打算用整个查询混淆这篇文章),包括4'Union All'语句,但否则主要过滤索引除了巨大的尺寸外,它非常有效。
使用的过滤器通过以下功能执行。
Function IsQueryStatus(Pni_QueryStateId in number,
Pni_Query_Id in number) return pls_integer as
vn_count pls_integer;
Begin
select count(1)
into vn_count
from m_query mq
where mq.id = Pni_Query_Id
and mq.state_id = Pni_QueryStateId;
return vn_count;
End;
关于什么可能导致较小的结果集执行比大结果集差得多的任何想法?
答案 0 :(得分:3)
我认为你面临的情况是确定集合中不的东西比确定集合中的 要花费更长的时间。这可能经常发生。例如,如果m_query(id)
上有索引,那么请考虑如何执行where
子句:
(1)在索引中查找值Pni_Query_Id
。没有比赛。查询的值为0
。
(2)有很多比赛。现在,让我们获取state_id
所在的网页,并与Pni_QueryStateId
进行比较。哦,那还有很多工作。
如果是这种情况,那么在m_query(id, state_id)
上设置索引应该有助于查询。
顺便说一句,假设仅更改在where
子句中的函数调用中。如果有其他更改可以获得更少的行,您可能只是更少次地调用此函数。