2

我在 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;

关于可能导致较小结果集的性能比大结果集差得多的任何想法?

4

1 回答 1

3

我认为你正面临这样一种情况,即确定某物不在系列中比确定它是否在系列中要花费更长的时间。这可能经常发生。例如,如果有一个索引 on m_query(id),那么考虑如何where执行该子句:

(1)Pni_Query_Id在索引中查找值。没有比赛。查询以 的值完成0

(2) 有一堆火柴。现在,让我们获取所在的页面state_id并与Pni_QueryStateId. 哦,这还有很多工作。

如果是这种情况,那么有一个索引m_query(id, state_id)应该有助于查询。

顺便说一句,这是假设唯一的变化是where子句中的函数调用。如果有其他更改来获得更少的行,您可能只是更少地调用此函数。

于 2013-07-02T19:58:01.017 回答