Oracle_spatial的常見錯(cuò)誤與注意事項(xiàng)

1、ORA-13226:沒有空間索引接口將不被支持
當(dāng)使用一個(gè)空間操作符時(shí),如果沒有使用空間索引導(dǎo)致該操作符不能被完成將會返回該錯(cuò)誤。這可能會發(fā)生在當(dāng)你使用的列上沒有空間索引、或者優(yōu)化器沒有選擇以所用為基礎(chǔ)進(jìn)行計(jì)算時(shí)。

解決辦法:如果在空間操作符的列上沒有索引,就創(chuàng)建一個(gè)索引。如果優(yōu)化器沒有選擇空間索引,那么久顯式地指定index或ordered以確??臻g索引被使用。

例如:

select b.gwm_fid, b.gwm_fno, b.gwm_vno, a.gwm_tileid, b.districtid

 from gs_tile_p2 a, VP_street_area b

 where b.gwm_vno = 13001

   and b.deletetag = 0

   and b.gwm_status = 0

   and sdo_relate(a.gwm_geometry, b.gwm_geometry, '' MASK = ANYINTERACT '') = '' TRUE '';

查詢提示該錯(cuò)誤,原因gs_tile_p2該表沒有創(chuàng)建控件索引。
## 2、ORA-13203:讀取USER_SDO_GEOM_METADATA視圖失敗

如果在USER_SDO_GEOM_METADATA視圖中對沒有任何元數(shù)據(jù)的表進(jìn)行索引,就會返回該錯(cuò)誤。

解決辦法:在該視圖中插入一條與空間層相關(guān)的記錄。

比如:

CREATE INDEX INDEX_GS_TILE_P2 ON GS_TILE_P2(GWM_GEOMETRY)INDEXTYPE IS MDSYS.SPATIAL_INDEX;

提示ORA-13203錯(cuò)誤,經(jīng)查詢發(fā)現(xiàn)沒有在元數(shù)據(jù)中插入記錄。

INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)

 VALUES ('GS_TILE_P2', 'GWM_GEOMETRY',

    MDSYS.SDO_DIM_ARRAY

      (MDSYS.SDO_DIM_ELEMENT('X', -5000000, -5000000, 0.000000050),

       MDSYS.SDO_DIM_ELEMENT('Y', -5000000, -5000000, 0.000000050),

       MDSYS.SDO_DIM_ELEMENT('Z', 0,0, 0.000000050) 

     ),

     NULL);

## 3、ORA-13365:層的SRID與幾何體的SRID不符

該錯(cuò)誤暗示著在一個(gè)表的幾何體中的SRID與USER_SDO_GEOM_METADATA視圖中相應(yīng)的SRID值不符。

解決辦法:將兩者的SRID設(shè)為一致。

## 4、       ORA-13223:SDO_GEOM_METADATA

## 中<table_name,column_name>的重復(fù)項(xiàng)

該錯(cuò)誤表明,像USER_SDO_GEOM_METADATA視圖中插入一條指定了<table_name,column_name>數(shù)據(jù)對的新記錄失敗。表明該視圖中已經(jīng)含有<table_name,column_name>數(shù)據(jù)對的記錄。

解決辦法:在向該視圖插入新記錄前,先刪除含有<table_name,column_name>數(shù)據(jù)對的記錄。

## 5、ORA-13249,ORA-02289:不能撤銷序列/表

當(dāng)你撤銷一個(gè)空間索引時(shí)可能引發(fā)該錯(cuò)誤。如果相應(yīng)的序列/表不存在,DROP INDEX語句會引發(fā)這些錯(cuò)誤。 解決辦法:在DROP INDEX語句中增加FORCE。

如:DROP INDEX customers_sidx FORCE;

## 6、ORA-13249:sdo_index_metadata表在有重復(fù)條目

當(dāng)嘗試創(chuàng)建一個(gè)空間索引,且此時(shí)還有失敗的DROP INDEX語句殘留元數(shù)據(jù)時(shí),該錯(cuò)誤將會引發(fā)。

解決辦法:顯式地清除MDSYS模式中SDO_INDEX_METADATA表內(nèi)指定索引的元數(shù)據(jù)。

DELETE FROM SDO_INDEX_METADATA WHERE sdo_index_owner = ‘SPATIAL’ AND sdo_index_name = ‘CUSTOMERS_SIDX’;

## 7、ORA-13207:不正確地使用<operator-name>操作符

當(dāng)指定的操作符使用 不正確時(shí)可能引發(fā)該錯(cuò)誤。絕大多數(shù)情況下,當(dāng)SDO_RELATE、SDO_NN或SDO_WITHIN_DISTANCE操作符被應(yīng)用到三維或四維空間索引時(shí)(通過在CREATE INDEX語句中的字句中指定SDO_INDEX_DIMS參數(shù)創(chuàng)建索引),可能引發(fā)該錯(cuò)誤。

解決辦法:在索引創(chuàng)建過程中,如果SDO_INDEX_DIMS參數(shù)被設(shè)置為大于2(默認(rèn)操作符>值)時(shí),可以使用的操作符只有SDO_FILTER。

## 8、ORA-13000:維數(shù)超出范圍

     當(dāng)操作含有SDO_GTYPE值(在SDO_GEOMETRY對象中)小于10的幾何體時(shí),將會導(dǎo)致該錯(cuò)誤。也許是因?yàn)樵缙诘腛racle spatial版本中的SDO_GTYPE僅僅包含類型(T)信息。從Oracle9i開始,SDO_GEOMETRY中的SDO_GTYPE的格式為DOOT,其中D表明維度而T是類型信息。

解決辦法:修改數(shù)據(jù)使其符合這一變化。另一種方法是使用SDO_MIGRATE.TO_CURRENT函數(shù)讓Oracle spatial改變數(shù)據(jù)。

## 9、ORA-00904:…無效的標(biāo)識符

select gwm_geometry.sdo_srid from p_street_area進(jìn)行查詢時(shí)就會提示該錯(cuò)誤

這是因?yàn)橐脤ο蟮膶傩詴r(shí)沒有為表指定一個(gè)別名。如下操作就可以正常查詢:

select a.gwm_geometry.sdo_srid from p_street_area a;

## 10、ORA-00939:函數(shù)參數(shù)過多

當(dāng)SDO_ORDINATES數(shù)組中插入一個(gè)超過1000個(gè)坐標(biāo)的SDO_GEOMETRY時(shí),可能引發(fā)該錯(cuò)誤。

例如:

INSERT INTO sales_regions

VALUES

 (1000,

   sdo_geometry(2004,

                8307,

                NULL,

                sdo_elem_info_array(1, 1, 1100),--1100個(gè)點(diǎn)

                sdo_ordinate_array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.. . --重復(fù)99次

                                   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

                                   )));

提示too many arguments for function

解決辦法:這是一個(gè)sql級別的限制??梢酝ㄟ^創(chuàng)建一個(gè)保存該幾何體的pl/sql變量來避免這一錯(cuò)誤,之后將該變量綁定到insert sql語句中:

DECLARE

 geom sdo_geometry;

BEGIN

 geom:=

    sdo_geometry

               (2004,

                8307,

                NULL,

                sdo_elem_info_array(1, 1, 1100),--1100個(gè)點(diǎn)

                sdo_ordinate_array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.. . --重復(fù)99次

                                   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

                                   )

                 );

execute immediate

 'INSERT INTO sales_regions values (1000,:gm)' using geom;

END;

## 11、ORA-13030:sdo_geometry的維數(shù)無效或者ORA-13364:層維數(shù)與幾何體維數(shù)不符

空間索引、元數(shù)據(jù)中的diminfo,數(shù)據(jù)表中sdo_geometry中的GTYPE值要保持一致。

如果空間索引是2維的,就無法將數(shù)據(jù)表中二維坐標(biāo)轉(zhuǎn)換為三維的,必須將該索引先drop,然后更新坐標(biāo)為三維,最后創(chuàng)建空間索引。

# Oracle spatial的使用注意事項(xiàng)

## 1、數(shù)據(jù)建模和數(shù)據(jù)裝載

### 1.1 始終驗(yàn)證數(shù)據(jù)的有效性

通過驗(yàn)證函數(shù)SDO_GEOM.VALIDATE_*執(zhí)行驗(yàn)證?;蛘咄ㄟ^SDO_MIGRATE.TO_CURRENT函數(shù)修正任何無效多邊形幾何體的取向。

網(wǎng)絡(luò)模型就應(yīng)使用SDO_NET.VALIDATE_NETWORK函數(shù)來驗(yàn)證網(wǎng)絡(luò)的有效性。

1.2 始終將二維點(diǎn)和三維點(diǎn)存儲在SDO_POINT中

為了存儲二維點(diǎn)和三維點(diǎn)應(yīng)當(dāng)一直使用SDO_GEOMETRY數(shù)據(jù)類型的SDO_POINT屬性。把SDO_ELEM_INFO和SDO_ORDINATES屬性設(shè)置為NULL。這樣可以確保更少的存儲要求和更快的存儲速度。

1.3 使用TO_CURRENT修正多邊形幾何體的取向

Oracle spatial需要多邊形幾何體的邊界是逆時(shí)針取向的。如果多邊形為順時(shí)針取向, 可以通過該函數(shù)改變它的取向。

1.4 使用SDO_UNION函數(shù)修正一個(gè)自交的多邊形

對于一個(gè)自交的多邊形進(jìn)行驗(yàn)證時(shí)會提示多邊形邊界穿過自身的錯(cuò)誤,因此通過該函數(shù)可以得到修正。

1.5 始終存儲需要的維數(shù)或位數(shù)

一個(gè)三維的幾何體,每個(gè)點(diǎn)就有三個(gè)坐標(biāo),而第三個(gè)點(diǎn)坐標(biāo)往往是0值,如果將這些0值清除會省出很多空間。

另外,坐標(biāo)值中的小數(shù)點(diǎn)位,根據(jù)需要來取,減少小數(shù)點(diǎn)位數(shù)可以減少存儲空間,并提高幾何體的輸入輸出性能。

2、       空間查詢操作符的性能

2.1 指定LAYER_GTYPE參數(shù)

    如果表僅包含單純的點(diǎn)數(shù)據(jù)或線數(shù)據(jù)或面數(shù)據(jù),在創(chuàng)建索引時(shí)指定LAYER_GTYPE參數(shù)的值,這樣就可以提高查詢。

3、       空間處理函數(shù)的性能

3.1 為存儲函數(shù)指定DETERMINISTIC

3.2 SDO_AGGR_UNION使用分治法

分組進(jìn)行并運(yùn)算

4、       插入、刪除、更新的性能

在一個(gè)表的一個(gè)或多個(gè)列上建立了空間索引,那么在該表上的插入、刪除、更新操作將花費(fèi)更長時(shí)間,因?yàn)樗饕獙?shí)時(shí)更新。

方法一、在修改大量記錄之前先將索引撤銷(修改表中超過30%的記錄左右),之后再創(chuàng)建索引

注:如果空間索引撤銷,就不能執(zhí)行空間操作符的操作

方法二、

在同一事務(wù)中,如果批量執(zhí)行插入、刪除或更新操作,就能夠最小化空間索引的性能開銷。如果想要在一個(gè)典型的事務(wù)中執(zhí)行1000多個(gè)那樣的操作(該建議適用于每個(gè)事務(wù)含有超過1000個(gè)的插入、刪除或更新操作),可以通過指定create INDEX語句的參數(shù)sdo_dml_batch_size微調(diào)以下性能。默認(rèn)情況下,被設(shè)置為1000.當(dāng)然如果批量修改的量大,也可以根據(jù)實(shí)際情況修改。

create index cola_markets_spatial_geo_idx on cola_markets(LOCATION)

indextype is mdsys.spatial_index

 parameters ('sdo_dml_batch_size=5000');

sdo_dml_batch_size的值應(yīng)該在1-10000之間,如果超過10000將會導(dǎo)致許多內(nèi)存消耗,并不能帶來明顯的性能改善。

如果已經(jīng)創(chuàng)建了空間索引,就能夠?yàn)樘囟ǖ目臻g索引手動地在MDSYS模式的SDO_INDEX_METADATA_TABLE表(USER_SDO_INDEX_METADATA和USER_SDO_INDEX_INFO字典視圖)中修改這一參數(shù)。注意,不能修改該表中的其他參數(shù),否則會導(dǎo)致使用空間操作符的操作失敗。

5、       空間索引的擴(kuò)展性和可操縱性

5.1使用表分區(qū)(和本地空間索引)

Oracle的表分區(qū)特性及本地空間索引的使用

表的分區(qū):

CREATE TABLE weather_patterns

(

 gid NUMBER,

 geom SDO_GEOMETRY,

 creation_date VARCHAR2(32)

)

PARTITION BY RANGE(creation_date)

(

 PARTITION p1 VALUES LESS THAN ('2000-01-01') TABLESPACE tbs_3,

 PARTITION p2 VALUES LESS THAN ('2001-01-01') TABLESPACE tbs_3,

 PARTITION p3 VALUES LESS THAN ('2002-01-01') TABLESPACE tbs_3,

 PARTITION p4 VALUES LESS THAN ('2003-01-01') TABLESPACE tbs_3,

 PARTITION p5 VALUES LESS THAN ('2004-01-01') TABLESPACE tbs_3,

 PARTITION jan VALUES LESS THAN ('2004-02-01'),

 PARTITION feb VALUES LESS THAN ('2004-03-01'),

 PARTITION current_month VALUES LESS THAN (MAXVALUE)

);

weather_patterns表基于creation_date列創(chuàng)建了一個(gè)分區(qū)表。前5個(gè)分區(qū)指定了表空間,后幾個(gè)沒有指定表空間默認(rèn)被存儲到當(dāng)前表所在的表空間。

為表創(chuàng)建一個(gè)本地分區(qū)空間索引,即每個(gè)分區(qū)創(chuàng)建一個(gè)獨(dú)立的索引(創(chuàng)建空間索引之前要在元數(shù)據(jù)表中插入相應(yīng)的記錄):

CREATE INDEX weather_patterns_sidx on weather_patterns(geom)

INDEXTYPE IS mdsys.spatial_index LOCAL;

5.2 本地索引創(chuàng)建為UNUSABLE

CREATE INDEX weather_patterns_sidx on weather_patterns(geom)

INDEXTYPE IS mdsys.spatial_index LOCAL UNUSABLE;

指定為UNUSABLE后,該索引只是一個(gè)虛構(gòu)的索引,任何空間查詢操作符,表上的查詢、插入、刪除、更新操作或者指定的分區(qū)等,將引發(fā)一個(gè)錯(cuò)誤,指出分區(qū)是UNUSABLE。

因此,處理前應(yīng)當(dāng)重建分區(qū)上的索引。

5.3為每個(gè)分區(qū)單獨(dú)重建空間索引

如下:

ALTER INDEX weather_patterns_sidx REBUILD PARTITION p1;

同樣,可以為每個(gè)分區(qū)分別重建本地索引。通過在多個(gè)SQL*PLUS會話中重建那些索引,可以實(shí)現(xiàn)并行操作。

分別重建本地索引將在分區(qū)索引創(chuàng)建上提供更多的控制權(quán)。如一個(gè)分區(qū)失敗,整個(gè)索引并沒有被標(biāo)識為失敗。即不必為所有的分區(qū)重建索引。相反,只需對創(chuàng)建失敗的分區(qū)重建索引。

可以采用ALTER TABLE…REBUILD UNUSABLE INDEXES 命令一次性地為一個(gè)分區(qū)重建所有的UNUSABLE索引。

ALTER TABLE weather_patterns_sidx REBUILD PARTITION p1 UNUSABLE LOCAL INDEXES;

5.4在索引創(chuàng)建失敗的分區(qū)上使用交換分區(qū)

重建空間索引可能因?yàn)槟硞€(gè)原因?qū)е率?,原因主要有分區(qū)指定的表空間空間不足或者在表分區(qū)的索引列中存在無效的幾何體。如果增加表的大小后,再重新執(zhí)行空間索引的重建操作,索引將被成功創(chuàng)建。但是如果分區(qū)中存在無效的幾何體,重新執(zhí)行索引的重建語句將不起作用。此時(shí),將不能更新或刪除與無效幾何體相應(yīng)的記錄。Oracle對于那些操作或許會產(chǎn)生“分區(qū)被標(biāo)記為faild/unusable”的錯(cuò)誤。

為避免上述錯(cuò)誤,在創(chuàng)建空間索引之前應(yīng)該對數(shù)據(jù)進(jìn)行驗(yàn)證。

如果出現(xiàn)了“索引失敗”的情況,可通過交換分區(qū)的方法解決:

首先創(chuàng)建一個(gè)臨時(shí)表tmp,結(jié)構(gòu)與之一樣。然后在tmp表中創(chuàng)建一個(gè)空間索引。然后執(zhí)行如下分區(qū)操作:

ALTER TABLE weather_patterns EXCHANGE PARTITION current_month WITH TABLE tmp EXCLUDING INDEXES;

此時(shí),tmp表將會有先前weather_patterns表p1分區(qū)的數(shù)據(jù)。由于tmp表不是一個(gè)分區(qū)表,所以可以在該表上執(zhí)行常規(guī)的DML操作并更正表中無效幾何體記錄。修正好后,在執(zhí)行上sql語句將正確數(shù)據(jù)放回p1分區(qū)中。

5.5對新數(shù)據(jù)使用含有索引的交換分區(qū)

如果每天有大量數(shù)據(jù)更新到current_month分區(qū)中,如何確保current_month分區(qū)中的數(shù)據(jù)實(shí)時(shí)更新?

方法一:采用批量的更新

方法二:創(chuàng)建一個(gè)臨時(shí)表tmp,與上述5.4介紹的類似,同交換實(shí)現(xiàn)更新,只是在更新時(shí)也包括索引。

ALTER TABLE weather_patterns EXCHANGE PARTITION current_month WITH TABLE tmp INCLUDING INDEXES;

5.6拆分分區(qū)

ALTER TABLE weather_patterns

SPLIT PARTITION current_month AT ('2010-04-1') INTO

(

 PARTITION march,

 PARTITION current_month

);

5.7合并分區(qū)

MERGE PARTITION jan,PARTITION feb INTO PARTITION janfeb;

對一個(gè)分區(qū)重命名

ALTER INDEX weather_patterns_sidx RENAME PARTITION janfeb TO jan;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容