我有一个表(granule
),其中包含大约400万个目前SRID = 8307的唯一几何对象。
我正在尝试使用相同的数据创建一个SECOND表,但使用笛卡尔坐标系。
我创建了表格,
create table granule_cartesian (
granule varchar(64) not null,
SHAPE sdo_geometry NOT NULL );
并插入正确的geom_metadata
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values ( 'GRANULE_CARTESIAN', 'SHAPE',
mdsys.sdo_dim_array(
mdsys.sdo_dim_element('longitude', -180, 180, .5),
mdsys.sdo_dim_element('latitude', -90, 90, .5)),
null);
现在我想将granule的几何内容复制到granule_cartesian。
显然,由于SRID不匹配,直接副本无法正常工作。
我可以通过转换为wkt并返回几何体来一次复制几个,剥离SRID:
insert into granule_cartesian
select granule,
SDO_GEOMETRY(SDO_UTIL.TO_WKTGEOMETRY(shape), null) as shape
from granule
where platform = 'ZZ'; -- granule has a few other columns...
如果我选择小于~10k(约+/- 10分钟)的颗粒表子集,则此方法有效。任何超过10K和几小时的运行,有时不合理地断开我。
似乎应该有一种方法可以做到这一点而不做< 10K块。除了将FOREVER实际迁移之外,这将对我们的主动和动态生产数据库造成严重的后勤噩梦。我尝试过像这样使用SDO_CS.TRANSFORM:
SDO_CS.TRANSFORM(geom => shape, to_srid => null )
...但是oracle在这里不会接受NULL SRID:
12:57:49 [SELECT - 0 row(s), 0.000 secs] [Error Code: 1405, SQL State: 22002] ORA-01405: fetched column value is NULL
ORA-06512: at "MDSYS.SDO_CS", line 114
ORA-06512: at "MDSYS.SDO_CS", line 152
ORA-06512: at "MDSYS.SDO_CS", line 5588
ORA-06512: at "MDSYS.SDO_CS", line 3064
SDO_CS.TRANSFORM_LAYER将拒绝接受NULL SRID。
经过广泛搜索后,我找不到任何方法来进行精简大地测量 - >笛卡尔(SRID = NULL)转换。除了暴力小批量之外,有没有人有任何想法?
编辑
1)对于Clarity,我理解我可以使用PL / SQL分解并执行450个10K行的块。但是每块大约@~470秒,仍然是2.5天的执行时间。这是一个最佳案例。使用update granule set shape.srid = 8307
更改投影/坐标系非常快且容易。使用insert into granule select SDO_CS.TRANSFORM(geom => shape, to_srid => 8307 ) ....
将坐标系从笛卡儿更改为大地测量是快速且简单的。我正在寻找的是从大地测量到笛卡尔的同样简单/快速的解决方案。
2)试图插入300K作为测试。它跑了大约10个小时就像这样死了:
20:06:59 [INSERT - 0 row(s), 0.000 secs] [Error Code: 4030, SQL State: 61000] ORA-04030: out of process memory when trying to allocate 8080 bytes (joxcx callheap,f:CDUnscanned)
ORA-04030: out of process memory when trying to allocate 8080 bytes (joxcx callheap,f:CDUnscanned)
ORA-04030: out of process memory when trying to allocate 16328 bytes (koh-kghu sessi,kgmtlbdl)
ORA-06512: at "MDSYS.SDO_UTIL", line 2484
ORA-06512: at "MDSYS.SDO_UTIL", line 2511
这是一个强大的企业级服务器,只有oracle。我们最近有一个Oracle顾问(来自Oracle)分析我们所有的数据库系统(包括这个)。它给了一个干净的健康状况。
答案 0 :(得分:0)
数据库出了问题。我有6400万行的geom表(北美的每个映射道路 - 是的,加拿大,美国和墨西哥),我经常执行sdo_anyinteract / sdo_contains查询,并在不到5秒的时间内获得200平方英里的响应。
要首先执行此操作,请删除所有索引并关闭目标表或表空间上的日志记录。如果您没有权限,请询问您的DBA,但命令是:
alter table [table] nologging ; or alter tablespace [tablesspace] nologging ;
这应该会让你失去重做空间,但如果你的重做空间不足,你的DBA应该通过添加重做段来解决这个问题。
使用游标,因为必须在接收WKT时添加SRID,因为必须在SDO对象上设置SRID。
declare
newGeom sdo_geometry ;
begin
for rec in ( select statement ) loop
newGeom := sdo_util.to_wktgeometry(rec.geom);
newGeom.sdo_srid := [srid that matches the target ] ;
insert into [table] (geom column, ... )values( newGeom, ... );
end loop;
commit ;
end ;
有400万行,这应该在几分钟内发生,如果不是你的数据库严重失控。
确保您与DBA一起工作
当流程完成后,重建此域索引。这可能需要几个小时。上次我在6400万行上做了它花了3天。您必须了解R-Trees本质上是索引中的索引,并使用最小边界矩形来获得速度,并且它们需要长时间来构建,因为每个插入代表来自 root的遍历强>指数。
您可以使用 BULK COLLECT 之类的东西,但这对于这个地方来说很复杂。我建议如果您还没有,请获取Oracle帐户(它们是免费的)并在数据库下的Oracle论坛中提出类似的问题 - >空间
答案 1 :(得分:0)
BrianB, 抱歉,我只是无法理解您在尝试使用SDO_GEOMETRY(SDO_UTIL.TO_WKTGEOMETRY(shape),null)进行转换。如果我做对了,生成的几何体将具有与源形状相同的几何类型,点,线段和纵坐标。 所以,如果这是真的,你可以使用其中一个:
create table granule_cartesian (
granule varchar(64) not null,
SHAPE sdo_geometry NOT NULL );
insert into granule_cartesian
select granule, shape
from granule
where platform = 'ZZ'; -- granule has a few other columns...
update granule_cartesian t
set t.shape.sdo_srid = null;
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values ( 'GRANULE_CARTESIAN', 'SHAPE',
mdsys.sdo_dim_array(
mdsys.sdo_dim_element('longitude', -180, 180, .5),
mdsys.sdo_dim_element('latitude', -90, 90, .5)),
null); -- add metadata after all rows are updated to null srid
或者,如果由于某种原因你讨厌插入然后更新,还有另一种方法:
insert into granule_cartesian
select granule, mdsys.sdo_geometry (t.shape.SDO_GTYPE, null, t.shape.SDO_POINT, t.shape.SDO_ELEM_INFO, t.shape.SDO_ORDINATES)
from granule t
where platform = 'ZZ'; -- granule has a few other columns...
在这种情况下,在将行插入granule_cartesian之前,您可以在user_sdo_geom_metadata表中添加一行甚至是空间索引。
第h。祝你好运。