2016-06-16 53 views
3

我的应用程序使用的视图必须保持通用(无过滤器),其中包括分析函数RANKDENSE_RANK。例如,我有一个观点MYVIEWOracle缓慢的RANK函数

SELECT 
RANK() OVER (PARTITION BY FIELD1 ORDER BY FIELD2) RANK, 
FIELD2, 
FIELD3 
FROM TABLE1; 

我的应用程序,然后在运行时即应用必要的过滤器

SELECT * FROM MYVIEW WHERE FIELD3 IN ('a','b','c'); 

我的查询是非常快的,而不RANK函数,但痛苦的缓慢(2+分钟)与它(我得到正确的结果,只是缓慢)。底层表有250,000多行,我无法控制它的设计。我无法进一步分割它。所以速度很慢,因为每次调用视图时,它都会为FIELD1中的每个唯一条目创建分区?任何其他方式来避免这种情况?有关如何使这个更快的建议?

+2

您是否试过查看查询计划? – mustaccio

+1

我希望它首先应用过滤器(谓词推送)并将排名应用于匹配的行。但执行计划将揭示发生了什么。您是否得到您期望的排名值 - 即它们是否与结果集相邻,还是在应用过滤器之前有评估差距? (你想要什么?) –

+1

@Alex Pole,谓词推动'FIELD3 IN('a','b','c');'在这种情况下条件不起作用,因为这是一种物化子查询: SELECT ... FROM(子查询/视图中的数字行)where FIELD3 IN('a','b','c');' - 此查询必须先将数字分配给所有行,然后选择一些行,但whithour改变数字。我想'table1(FIELD1,FIELD2)'上的一个简单的多列索引可以提高查询速度。 – krokodilko

回答

0

正如在评论中提到的,与视图的解析函数,Oracle无法采取任何快捷方式(谓语推),因为

    在你看来
  • ,你已经创建了一个协议,与甲骨文:每当在访问视图时,RANK应该基于表中的所有行 - 没有指定WHERE子句
  • 查询视图时,“外部”WHERE子句决不应该影响视图生成的行的外观,但只有该行是否保留
  • 解析函数查看其他行以生成值所以如果你改变这些行(过滤),你可以改变这个值 - 推动一个谓词很容易影响这些函数产生的值如果发生这种情况,你的视图结果可能变得非常不一致(取决于优化器的选择评估查询)

因此,根据您所提供的细节,你的查询需要这样进行评估:

SELECT * 
    FROM (
     SELECT 
       RANK() OVER (PARTITION BY FIELD1 ORDER BY FIELD2) RANK, 
       FIELD2, 
       FIELD3 
      FROM TABLE1 
     ) myview 
WHERE <condition>; -- rankings are not affected by external conditions 

此:

SELECT * FROM (
    SELECT 
      RANK() OVER (PARTITION BY FIELD1 ORDER BY FIELD2) RANK, 
      FIELD2, 
      FIELD3 
     FROM TABLE1 
    WHERE FIELD3 IN ('a','b','c') -- ranking is affected by the conditions 
) 

那么,有没有办法让这个更快?也许。

  1. 如果对表进行分区,那么可以考虑使用并行查询。
  2. 索引可以帮助吗?

不是通常意义上的。由于视图本身没有条件,因此它会执行全表扫描以考虑排名的所有行,并且在应用WHERE子句时,使用索引进行筛选为时已晚。但是,如果您有一个“覆盖”查询的索引,即仅对正在使用的列有一个索引(例如,按照该顺序的FIELD1,FIELD2,FIELD3),索引可以用作更小的索引版本的表(而不是FULL TABLE SCAN,计划会显示INDEX FAST FULL SCAN。)作为奖励,因为它已经排序,所以在计算FIELD1上的分区,然后在每个分区内的FIELD2上进行排序可能是有效的。

  1. 另一种选择是将其作为一个物化视图,但如果您的数据经常发生变化,保持最新状态可能会很痛苦。

  2. 最后一个想法与在分区选项之前使用的“穷人的”分区类似。 (对不起,我无法找到一个描述就是一个很好的链接,但也许你已经听说过呢。)

这是真的只有一种选择,如果:

  1. 您分区列具有相对小数量的不同值的
  2. 那些值不改变
  3. 你知道你可以用什么分区值的数据隔离在查询
  4. 甲骨文愿意就推动谓词当它是安全的这样做

鉴于甲骨文似乎不利于推动当涉及分析功能时谓词,我不会给这个成功的可能性很高。

如果你想了解更多信息,请告诉我。