0

I have the same database on 2 different Oracle servers, one is 11.2.0.1.0 and the other is 11.2.0.4.0. I have the same 2 geometry tables in both databases and run the following query on both servers. When run on an 11.2.0.1.0 version of Oracle, the query runs for a few minutes and I get results, the same query when run on 11.2.0.4.0 runs for about 3 seconds and returns no results.

The BLPUs table holds 36 million points and the PD_B2 table holds a polygon. I am trying to find all the points that fall in the polygon. Other spatial queries do return rows but it takes hours and hours whereas the table join suggested in the Oracle Spatial documentation, takes 15 minutes to return all the points.

SELECT /*+ ordered */ a.uprn 
FROM TABLE(SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')) c, blpus a, PD_B2 b 
WHERE c.rowid1 = a.rowid 
AND c.rowid2 = b.rowid; 

The spatial queryies below return SDO_ROWIDSET() when run on the 11.2.0.4 server

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;

On the 11.2.0.1 server they return results.

I have discovered that a much smaller table of points will work on 11.2.0.4 so it seems that there is a size limit on 11.2.0.4 when using SDO_JOIN where as 11.2.0.1 seems to cope with the large table.

Does anyone know why this is or if there is an actual limit on table size when using SDO_JOIN?

1 Answers1

0

This is strange. I see no reason why SDO_JOIN will not work the same way in 11.2.0.4. At least I have not seen that sort of behavior before. It looks like a bug to me and I suggest you file a service request with Oracle Support so we can take a look. You may need to provide a dump of the tables - or at least of a small enough subset that demonstrates the problem.

That said there are a few things to check: did you apply the 11.2.0.4 patch on the same database ? I.e. nothing changed in terms of table structures or content, grants, etc ?

When you say that the query returns no rows, does it do so immediately ? Or does it perform some processing before completing without anything being returned ?

How large is the PD_B2 table ?

What happens when you do:

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;

Does this also return nothing ?

What happens if you do

select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;

Both should return something that looks like this:

SDO_ROWIDSET(SDO_ROWIDPAIR('AAAW3LAAGAAAADmAAu', 'AAAW3TAAGAAAAg7AAC'), SDO_ROWIDPAIR('AAAW3LAAGAAAADmABE', 'AAAW3TAAGAAAAgrAAA'),...)

You will see this if you run the query in sqlplus. [If you use a GUI (like TOAD or SQLDeveloper) then you may not see that. All those GUIs have problems dealing with objects or arrays.]

But the fact that your 11.2.0.4 tests complete very quickly probably means that you get an empty result back, maybe like this:

SDO_ROWIDSET()

and that confirms that something did not work.

Now, from what you say PD_B2 only contains one row ? If so then there is no reason whatsoever to go via SDO_JOIN. A straightforward spatial query is easier to write. SDO_JOIN only makes sense when both tables being joined contain multiple rows. Then again, if one of the tables is very small (like the PD_B2 table in your case), then it anyway falls back to a simple query.

A simple query would look like this:

SELECT a.uprn 
FROM blpus a, PD_B2 b 
WHERE sdo_anyinteract (a.geoloc, b.geoloc) = 'TRUE';

Does this return what you expect in 11.2.0.4 ?

You may also want to examine the cost of the query and the query plan used. In sqlplus, do this:

set timing on
set autotrace traceonly

then run the above query. The effect is that sqlplus will not display any results - but it will still fetch and format the output: it will just not print them. At the end you will get a printout of the query plan used as well as some execution statistics and the elapsed time. Please add those results to your question.

Running the query from within your application should have a similar profile: similar response time and database-side costs - assuming you do fetch all the 1.3 million rows.

BTW, what do you do with those results ? Do you show them out as a report ? Do you save them into a table for later analysis ? Surely you do not want to show them all on a map ?

To clarify: SDO_JOIN is only for matching many to many geometries. For matching one to many, the simple SDO_ANYINTERACT() is what you need. As a matter of fact, SDO_JOIN will automatically fall back to a simple SDO_ANYINTERACT when one of the sets is very much smaller than the other. I can't see how SDO_JOIN could be faster in your circumstances (i.e. when searching for all objects that match one object) since it will perform the same as an SDO_ANYINTERACT and will require extra joins to the two tables.

Going back to the original issue - that of a difference in behavior in SDO_JOIN between 11.2.0.1 and 11.2.0.4 that IMO is definitely a bug that you need to report to Oracle Support.

Albert Godfrind
  • 1,978
  • 1
  • 12
  • 20
  • Thanks for your response. I have edited my original post with the extra info you requested. – Paula Dormer Feb 26 '15 at 11:20
  • The timings of the queries in 11.2.0.4 (3 seconds or less) seem to indicate that no match is found, and confirms the problem you indicate. But see also what happens with a simple query (the correct approach since PD_B2 contains just one row). Also how many rows do you expect to get back ? Given the long time it takes for the query to complete, it looks like it returns any rows ? What kind of data does BLPU contain, and what does PD_B2 represent ? – Albert Godfrind Feb 28 '15 at 15:10
  • Thanks again for your suggestions. I have edited my original post to try and shed more light on what I'm doing. Your simple query works but takes too long to get results. I have tried different polygons this one returns 1315048 of the 36537734 rows. – Paula Dormer Mar 02 '15 at 23:25
  • Let me clarify: SDO_JOIN is only for matching many to many geometries. For matching one to many, the simple SDO_ANYINTERACT() is what you need. As a matter of fact, SDO_JOIN will automatically fall back to a simple SDO_ANYINTERACT when one of the sets is very much smaller than the other. SDO_JOIN cannot possibly be faster in your circumstances (i.e. when searching for all objects that match one object). – Albert Godfrind Mar 10 '15 at 09:56
  • "Your simple query works but takes too long to get results". From what you say, that query returns 1.3 million rows. That will obviously take time - I mean just the fetching and passing the results to your application. Doing that from sqlplus will definitely take a long time as it needs to format and display the results on your terminal window. – Albert Godfrind Mar 10 '15 at 09:59