我有两个 Oracle 18c 表:
ply
— 多边形:4970 行。pnt
— 点数:3500 行。数据可以在这里查看:db<>fiddle.
我有一个查询选择至少与一个点相交的多边形。
SELECT objectid
FROM (SELECT ply.objectid,
row_number() over(partition by ply.objectid order by null) rn
FROM ply --ORDER BY NULL is intentional.
CROSS JOIN pnt --It doesn't matter what polygon row per OBJECTID gets selected.
WHERE sdo_anyinteract(ply.shape, pnt.shape) = 'TRUE'
)
WHERE rn = 1
OBJECTID
----------
1
2
3
4
5
...
1443 rows selected.
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1457 | 37882 | | 12851 (1)| 00:00:01 |
|* 1 | VIEW | | 1457 | 37882 | | 12851 (1)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK | | 1457 | 10M| 11M| 12851 (1)| 00:00:01 |
| 3 | NESTED LOOPS | | 1457 | 10M| | 10522 (1)| 00:00:01 |
| 4 | TABLE ACCESS FULL | PNT | 3500 | 12M| | 11 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID | PLY | 1 | 3848 | | 10522 (1)| 00:00:01 |
|* 6 | DOMAIN INDEX (SEL: 0.010000 %)| PLY_SHAPE | | | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN"=1)
2 - filter(ROW_NUMBER() OVER ( PARTITION BY "PLY"."OBJECTID" ORDER BY NULL )<=1)
6 - access("MDSYS"."SDO_ANYINTERACT"("PLY"."SHAPE","PNT"."SHAPE")='TRUE')
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
查询设计为每个多边形只选择一行。原因:我想要一个唯一的多边形列表,这些多边形至少与一个点相交。
查询比较慢
PLY_SHAPE
spatial/domain index 被使用,我认为是合适的相比之下,像 ArcGIS Pro 这样的桌面制图软件可以在 0.5 秒内在 RAM 中执行相同的操作。
问题:
查询性能能否提升?
作为一个新手,我的平庸办公电脑配备了地图软件,却胜过我们的企业级 Oracle 数据库,这让我感到惊讶。
您可以开始将 SDO_JOIN 与 SDO_ANYINTERACT 结合使用,然后从那里继续。
SELECT /*+ ordered use_nl (a,b) use_nl (a,c) */
b.objectid as point_object_id,
c.objectid as polygon_object_id
FROM
TABLE(sdo_join('PNT','SHAPE','PLY','SHAPE')) a,
PNT b,
PLY c
WHERE
a.rowid1 = b.rowid
AND a.rowid2 = c.rowid
AND SDO_GEOM.RELATE (b.shape, 'ANYINTERACT', c.shape, 1.0) = 'TRUE';