我有两张桌子。一个是空的,另一个有大约2万个记录。在这些记录中有几何列,它使用Oracle的SDO_PACKAGE。我必须找到这些记录之间的交叉点。 我写的pl / sql查询对我来说足够了,但只有2千条记录它消耗了20分钟。我尝试完成执行,但在330分钟内仍然会继续。因此,我可以改进这些查询以加快执行速度。
子问题:在插入部分,我应该使用缓冲区,最后通过批量插入插入还是其他什么?
注意:我使用的是oracle 11g和pl / sql开发人员。 FirstTable有20000条记录。 (几何) SecondTable初始为空。
declare
control1 number(1);
control2 number(1);
resultForStart varchar2(5);
resultForEnd varchar2(5);
BEGIN
FOR aRow IN (SELECT MI_PRINX, SDO_LRS.geom_segment_start_pt(geoloc) as startpoint, SDO_LRS.geom_segment_end_pt(geoloc) as endpoint FROM FirstTable)
LOOP
control1 :=0;
control2 :=0;
FOR bRow IN (SELECT * FROM SecondTable)
LOOP
select SDO_GEOM.RELATE(aRow.Startpoint,'anyinteract', SDO_LRS.geom_segment_start_pt(bRow.Geoloc),0.02) into resultForStart from dual;
select SDO_GEOM.RELATE(aRow.Endpoint,'anyinteract', SDO_LRS.geom_segment_end_pt(bRow.Geoloc),0.02) into resultForEnd from dual;
if (resultForStart='TRUE' AND control1=0 )
THEN
UPDATE SecondTable SET COUNTER=(bRow.Counter+1)
WHERE MI_PRINX=bRow.Mi_Prinx AND STARTEND=bRow.Startend;
control1 :=1;
END IF;
if (resultForEnd='TRUE' AND control2=0)
THEN
UPDATE SecondTable SET COUNTER=(bRow.Counter+1)
WHERE MI_PRINX=bRow.Mi_Prinx AND STARTEND=bRow.Startend;
control2 :=1;
END IF;
EXIT WHEN (control1 > 0 AND control2>0);
END LOOP;
if (control1 = 0)
THEN
Insert INTO SecondTable (MI_PRINX,STARTEND,GEOLOC) values (aRow.Mi_Prinx,'s',aRow.Startpoint);--default Counter 1
END IF;
if (control2 = 0)
THEN
Insert INTO SecondTable (MI_PRINX,STARTEND,GEOLOC) values (aRow.Mi_Prinx,'e',aRow.Endpoint);--default Counter 1
END IF;
control1 :=0;
control2 :=0;
END LOOP;
END;
答案 0 :(得分:2)
这里有提示:您似乎正在从表中读取行,然后更新它们。
FOR bRow IN (SELECT * FROM SecondTable)
LOOP
...
if (resultForStart='TRUE' AND control1=0 )
THEN
UPDATE SecondTable SET COUNTER=(bRow.Counter+1)
WHERE MI_PRINX=bRow.Mi_Prinx AND STARTEND=bRow.Startend;
如果必须这样做,请改用rowid:
FOR bRow IN (SELECT * FROM SecondTable)
LOOP
...
if (resultForStart='TRUE' AND control1=0 )
THEN
UPDATE SecondTable SET COUNTER=(bRow.Counter+1)
WHERE ROWID=bRow.rowid;
这将为您提供查找要更新的行的最快方法。