I have a custom view which queries spatial data from geometry columns and extracts latitude/longtitude values. However, the retrieval process is really slow, and takes upto 5 to 10 mins for the view data to be retrieved.
Here is my view:
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;
The G3E_GEOMETRY
column is of SDO_GEOMETRY
type. PolePoint table has 1,310,629 rows while PoleDetailPoint has 100. The data in this tables are updated on a daily basis, while the view is used for reporting purposes.
I tried rebuilding the spatial index using the status=cleanup
parameter. But that didn't make any difference.
Our version is Oracle 11.2.0.3.
Any tips on retrieving such type of views/data appreciated. Or any other spatial functions that I can use to achieve this faster?
Try using UNION ALL
instead of 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;
Another potential source of performance degradation comes from the fact that you are using two calls to SDO_UTIL.GET_VERTICES
one directly on P.G3E_GEOMETRY
and the other on a transform of P.G3E_GEOMETRY
you will essentially have a cross product of the two vertices lists, so for example if a particular P.G3E_GEOMETRY
contains 5 vertices, then you will end up with 5 * 5 records one for each of the 25 possible combinations of T and T2 for that 5 vertex P.G3E_GEOMETRY
. I don't know if the vertex order is maintained by the SDO_CS.TRANSFORM
function, but if it is, you could improve your performance by adding the and t1.id = t2.id
predicate to each half of your query:
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;