2015-09-03 27 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次。 –