Because generating and updating a spatial field is relatively expensive we want to avoid it when possible.
Here is the relevant bit of our schema:
+---------+---------------+
|LATITUDE |NUMBER(16,10) |
|LONGITUDE|NUMBER(16,10) |
|LOCATION |SDO_GEOMETRY(1)|
+---------+---------------+
there is a MDSYS SPATIAL_INDEX on the LOCATION.
the values of latitude and longitude rarely change. To avoid unnecessary updates, we had previously done a SELECT, compared the LATITUDE and LONGITUDE, and run a different query depending on if they were the same or not.
I’m looking to see if we can do in a single query: possibly faster.
I’ve got something like this currently:
UPDATE ...
SET ...
LOCATION = CASE
WHEN LATITUDE = :latitude AND LONGITUDE = :longitude
THEN LOCATION
ELSE SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(:longitude, :latitude, NULL), NULL, NULL)
END
Which works, and avoids the calculation but, but I’m wondering if it also will avoid index re-calculation. I’ve done a bit of searching and it seems a normal index will not be re-calculated if set to the same value in Oracle, but I could not fine anything specific for spatial indexes. I would not be surprised if they are different.
I was also looking into using something like this:
MERGE INTO ...
USING (SELECT 1 FROM DUAL)
ON (LATITUDE = :latitude AND LONGITUDE = :longitude)
WHEN MATCHED THEN UPDATE SET
/* update other things */
WHEN NOT MATCHED THEN UPDATE SET
/* update other things */
LATITUDE = :latitude,
LONGITUDE = :longitude,
LOCATION = SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(:longitude, :latitude, NULL), NULL, NULL)
I think this will work as well, but it is less maintainable, being both longer and having many duplicate lines in the update other things part. So it the first query will not trigger a re-index I would much prefer to use it.