2015-09-03 104 views
4

我有一个自定义视图,它从几何列中查询空间数据并提取纬度/经度值。但是,检索过程非常缓慢,需要5到10分钟才能检索视图数据。Oracle空间函数SDO_CS.Transform(值)结果非常慢

这是我的观点:

CREATE OR REPLACE FORCE VIEW PoleData 
(
    G3E_FID, 
    X_COORD, 
    Y_COORD, 
    LATITUDE, 
    LONGITUDE 
) 
AS 
    SELECT P.g3e_fid, 
      T2.X * 1000 AS x_coord, 
      T2.Y * 1000 AS y_coord, 
      T.Y AS latitude, 
      T.X AS longitude 
    FROM PolePoint P, 
      TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
      TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
    WHERE P.ltt_id = 0 
    UNION 
    SELECT P.g3e_fid, 
      T2.X * 1000 AS x_coord, 
      T2.Y * 1000 AS y_coord, 
      T.Y AS latitude, 
      T.X AS longitude 
    FROM PoleDetailPoint P, 
      TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
      TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
    WHERE P.ltt_id = 0; 

G3E_GEOMETRYSDO_GEOMETRY类型。 PolePoint表有1,310,629行,而PoleDetailPoint有100个。这些表中的数据每天更新,而视图用于报告目的。

我试着用status=cleanup参数重建空间索引。但是这没有什么区别。

我们的版本是Oracle 11.2.0.3。

任何有关检索这种类型的意见/数据的提示赞赏。或者我可以使用任何其他空间函数来更快地实现这一目标?

+0

为什么问题DOWNVOTED?能否提出评论意见的用户? – reggie

+0

如果在PolePoint和PoleDetailPoint中没有重叠,则可以使用'UNION ALL'而不是'UNION',那么数据库不必将结果区分开来。 – Sentinel

+1

你真的需要'联盟'吗?为什么你不使用'union all'? –

回答

1

尝试使用UNION ALL代替UNION

SELECT P.g3e_fid, 
     T2.X * 1000 AS x_coord, 
     T2.Y * 1000 AS y_coord, 
     T.Y AS latitude, 
     T.X AS longitude 
    FROM PolePoint P, 
     TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
     TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
WHERE P.ltt_id = 0 
UNION ALL 
SELECT P.g3e_fid, 
     T2.X * 1000 AS x_coord, 
     T2.Y * 1000 AS y_coord, 
     T.Y AS latitude, 
     T.X AS longitude 
    FROM PoleDetailPoint P, 
     TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
     TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
WHERE P.ltt_id = 0; 

性能退化的另一个潜在来源是事实,你正在使用两个调用SDO_UTIL.GET_VERTICES一个直接在P.G3E_GEOMETRY上,另一个调用P.G3E_GEOMETRY的变换,你将基本上有两个顶点列表的交叉乘积,例如,如果一个特定的ar P.G3E_GEOMETRY包含5个顶点,那么对于该5个顶点P.G3E_GEOMETRY的T和T2的25个可能组合中的每一个,您将以5 * 5个记录结束。我不知道如果顶点顺序是由SDO_CS.TRANSFORM功能维持,但如果是这样,你可以通过添加and t1.id = t2.id谓词查询各占一半提高你的表现:

SELECT P.g3e_fid, 
     T2.X * 1000 AS x_coord, 
     T2.Y * 1000 AS y_coord, 
     T.Y AS latitude, 
     T.X AS longitude 
    FROM PolePoint P, 
     TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
     TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
WHERE P.ltt_id = 0 
    AND T.ID = T2.ID 
UNION ALL 
SELECT P.g3e_fid, 
     T2.X * 1000 AS x_coord, 
     T2.Y * 1000 AS y_coord, 
     T.Y AS latitude, 
     T.X AS longitude 
    FROM PoleDetailPoint P, 
     TABLE (
      SDO_UTIL.GETVERTICES (SDO_CS.TRANSFORM (P.G3E_GEOMETRY, 8265))) T, 
     TABLE (SDO_UTIL.GETVERTICES (P.G3E_GEOMETRY)) T2 
WHERE P.ltt_id = 0 
    AND T.ID = T2.ID; 
-1

您是否尝试将表格元素转换为with子句?

它们通常是很慢的,尤其是如果优化器决定运行它们在连接表中的每一行(检查结果集已经改变)

试试这个:

with t as (select * from table (sdo_util.getvertices (sdo_cs.transform (p.g3e_geometry, 8265)))), 
    t2 as (select * from table (sdo_util.getvertices (p.g3e_geometry))) 
select p.g3e_fid, 
     t2.x * 1000 as x_coord, 
     t2.y * 1000 as y_coord, 
     t.y as latitude, 
     t.x as longitude 
    from polepoint p, t, t2 
where p.ltt_id = 0 
union 
select p.g3e_fid, 
     t2.x * 1000 as x_coord, 
     t2.y * 1000 as y_coord, 
     t.y as latitude, 
     t.x as longitude 
    from poledetailpoint p, t, t2 
where p.ltt_id = 0; 

而且,你确定你需要"union"(强制排序过滤器)而不是"union all"? (即你希望重复的结果,如果不使用union all?)

问候 奥拉维尔

+0

由于它们依赖于极点表,因此无法使用with子句将表格元素拉出。注意p.g3e_geometry参考。 – Sentinel

+0

啊,当然是。我现在看到它。但这解释了为什么它如此缓慢。表(sdo_util.getvertices(...))在polepoint中每行运行2次,在poledetailpoint中每个单行运行2次。 –