查询大量数据以进行网页显示

时间:2011-08-18 14:21:47

标签: oracle plsql

我是Oracle的新手(知道一些基本的SQL),但任务以某种方式分配给我。

我的任务是优化查询。它连接一些大表(查询很耗时)并将结果返回到网页(可以使用分页)。

我的问题是我应该研究哪个方向?如果可以提供链接会更好。

以下是一些细节:

采取的优化方法

index on dayNum, timeNum, entityID columns  

行数:

  • time_seq:100,000
  • indicator_set:50,000,000
  • tity amount:1,000

查询:

select * 
  from time_seq seq,  
       (  
        select entityID, 
               dayNum,
               timeNum,
               sum(ind1) sum_ind1, 
               avg(ind2) avg_ind2, 
               max(ind3) max_ind3  
          from indicator_set  
         group by entityID, dayNum, timeNum 
         -- the dayNum timeNum are grouped to the time sequence standard 
         -- in time_seq table  
        ) sum  
where seq.entityID=sum.entityID  
  and seq.dayNum=sum.dayNum  
  and seq.timeNum=sum.timeNum  

表格time_seq

entityID, dayNum, timeNum
--------------------------------
object1, 20110818, 220000  
object1, 20110818, 223000  
object1, 20100818, 230000  
object1, 20110819, 220000  
object1, 20110819, 223000  
object1, 20100819, 230000 
object2, 20110818, 220000  
object2, 20110818, 223000   
object2, 20100818, 230000  
object2, 20110819, 220000  
object2, 20110819, 223000  
object2, 20100819, 230000  

表指标_set

entityID, dayNum, timeNUm, ind1, ind2, ind3
--------------------------------------------
object1, 20110818, 220000, 23,34,23
object1, 20110818, 220500, 23,54,543
object1, 20110818, 220530, 23,54,543
object1, 20110818, 220610, 23,54,543
object1, 20110818, 222900, 23,54,543
...

PS:抱歉,我没有提供表和查询的确切格式/详细信息。太复杂了。

欢呼声〜

3 个答案:

答案 0 :(得分:1)

您对此查询的结果有何看法?假设查询返回100,000行的顺序(我假设连接没有消除TIME_SEQ中的大量行),查询没有多大意义。您通过网页向用户返回100,000个无序行 - 人类无法翻阅100,000行,并且无法将这些行无序呈现(或者在中层)。

为了填充网页,尝试聚合5000万行数据是很有意义的。这将是一个固有的慢速操作 - 如果用户期望在一两秒内响应,你就没有时间阅读和汇总5000万行。您可以在INDICATOR_SET上创建可用于预聚合数据的物化视图。这将使插入和更新速度变慢,但应加快查询速度。

当然,即使您将5000万行预先聚合到仅100,000行,您仍然尝试加入两个100,000行表并向客户端发送100,000个无序行,这不太合理。您可以添加ORDER BY子句,以便行以合理的顺序排列,但这通常会增加查询的时间,因为您引入了额外的排序。根据您打算排序的内容,可能有一些方法可以对其进行优化。但是,我仍然回到了向人类客户端返回100,000行的根本问题,从根本上说这不是正确的方法。

答案 1 :(得分:0)

链接子查询中的indicator_set和time_seq表会限制在大的indicator_set表中分组的行数吗?

SELECT *
  FROM time_seq seq,
       (  SELECT ind.entityid,
                 ind.dayNum,
                 ind.timeNum,
                 SUM( ind.ind1 ),
                 AVG( ind.ind2 ),
                 MAX( ind.ind3 )
            FROM indicator_set ind,
                 time_seq ts
           WHERE ind.entity_id = ts.entityid
             AND ind.daynum    = ts.daynum
             AND ind.timenum   = ts.timenum
        GROUP BY ind.entityid,
                 ind.daynum,
                 ind.timenum) SUM
 WHERE seq.entityid = SUM.entityid
   AND seq.daynum   = SUM.daynum
   AND seq.timenum  = SUM.timenum

外部查询仍然会确保只从查询中返回time_seq表中的记录。

这有用吗?

编辑:顺便说一句,我使用比SUM更好的表别名,因为它是一个oracle函数。

答案 2 :(得分:0)

您可以根据查询创建实体化视图:

create materialized view mv as
select entityID, 
               dayNum,
               timeNum,
               sum(ind1) sum_ind1, 
               avg(ind2) avg_ind2, 
               max(ind3) max_ind3  
          from indicator_set  
         group by entityID, dayNum, timeNum;

这张表会更小。您也可以在此物化视图中创建索引。您的选择将是这样的:

select * 
  from time_seq seq,  
      mv sum  
where seq.entityID=sum.entityID  
  and seq.dayNum=sum.dayNum  
  and seq.timeNum=sum.timeNum;

您的物化视图可以在快速模式,正常等情况下重新打开...如果您想要更多信息,请查看: http://download.oracle.com/docs/cd/B13789_01/server.101/b10759/statements_6002.htm

http://orafaq.com/wiki/Oracle_Materialized_Views