在Oracle中:我有一个表空间,它记录了许多汽车的位置。每个记录都有里程、时间、经度和纬度。表空间有五列:“PLATENO”“SENDTIME”、“MILEAGE”和“LONGITUDE”“LATITUDE”。它们分别表示汽车的车牌号码、位置发送时间、里程和车辆的两个坐标。“SENDTIME”列中的值采用日期时间格式。我还有一些建筑物的坐标。我想找出那些经过建筑物附近200米的车辆。所以我创建了一个名为buildings的表来记录建筑物,类似于这样:
CREATE TABLE BUILDINGS (
NAME VARCHAR2(50) NOT NULL,
ADDR VARCHAR2(50) NOT NULL,
LONGITUDE NUMBER NOT NULL,
LATITUDE NUMBER NOT NULL
);
INSERT INTO BUILDINGS (NAME, ADDR, LONGITUDE, LATITUDE) VALUES (
'北京市大兴区永兴路7号院1号楼1F2F局部内装修工程', '北京市大兴区永兴路7号院1号楼',
116.314497, 39.685536);
INSERT INTO BUILDINGS (NAME, ADDR, LONGITUDE, LATITUDE) VALUES (
'北京金沃夫生物工程科技有限公司23号楼诊断试剂GMP生产车间及配套实验室、研发实验室建设项目', '北京市大兴区华佗路50号院',
116.282965, 39.668402);
然后我使用sdo_geom.sdo_distance函数计算距离,以找到满足我要求的记录。
select g.PLATENO, g.SENDTIME, g.MILEAGE, g.LONGITUDE, g.LATITUDE,
b.NAME as BUILDING_NAME, b.ADDR, b. LONGITUDE, b.LATITUDE
from GPSINFO g, BUILDINGS b
where sdo_geom.sdo_distance (
sdo_geometry (2001, 4326, sdo_point_type (g.LONGITUDE, g.LATITUDE, null), null, null),
sdo_geometry (2001, 4326, sdo_point_type (b.LONGITUDE, b.LATITUDE, null), null, null),
0.01,
'unit=M'
) <= 200;
但是查询运行得相当慢。我只需要三个符合条件的记录。如何优化我的代码?我尝试了先取,但它不工作:
select v.PLATENO, v.SENDTIME, v.MILEAGE, v.LONGITUDE, v.LATITUDE, b.NAME as BUILDING_NAME
from VEHICLES v, BUILDINGS b
where sdo_geom.sdo_distance (
sdo_geometry (2001, 4326, sdo_point_type (v.LONGITUDE, v.LATITUDE, null), null, null),
sdo_geometry (2001, 4326, sdo_point_type (b.LONGITUDE, b.LATITUDE, null), null, null),
0.01,
'unit=M'
) <= 50
and HAVERSINE(v.LONGITUDE, v.LATITUDE, b.LONGITUDE, b.LATITUDE) <= 50
ORDER BY v.SENDTIME DESC
FETCH FIRST 3 ROWS ONLY;
1条答案
按热度按时间n53p2ov01#
您可以将
longitude
和latitude
存储为NUMBER
数据类型,然后在查询中转换为SDO_GEOMETRY
,而不是将它们存储为SDO_GEOMETRY
类型并添加空间索引:然后你可以插入数据:
如果要获取位置的组件,则可以使用嵌套对象(注意:您需要确保从表别名开始):
其输出:
| 名称|地址|纵向|纬度|
| - -----|- -----|- -----|- -----|
| 北京市大兴区永兴路7号院1号楼1F2F局部内装修工程 | 北京市大兴区永兴路7号院1号楼 | 116.314497 | 39.685536 |
| 北京金沃夫生物工程科技有限公司23号楼诊断试剂GMP生产车间及配套实验室、研发实验室建设项目 | 北京市大兴区华佗路50号院 | 116.282965 | 39.668402 |
您可以对
GPSINFO
表进行相同的更改,这样您的查询就不需要在运行时生成大量对象,并且您可以利用索引。您也不需要同时使用空间比较和
HAVERSINE
函数。fiddle