我是Oracle的新手(知道一些基本的SQL),但任务以某种方式分配给我。
我的任务是优化查询。它连接一些大表(查询很耗时)并将结果返回到网页(可以使用分页)。
我的问题是我应该研究哪个方向?如果可以提供链接会更好。
以下是一些细节:
采取的优化方法
index on dayNum, timeNum, entityID columns
行数:
查询:
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:抱歉,我没有提供表和查询的确切格式/详细信息。太复杂了。
欢呼声〜
答案 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