1. R樹空間索引
自然界中的幾何對象都是奇形怪狀的,對這樣的資料進行管理是一件很頭疼的事情。因此,GIS的工程師們化繁為簡,一種方法就是把幾何對象的邊界範圍拿出來作為一個檢索的依據(幾何對象肯定在它內部),這是一個矩形的範圍,再對它進行管理就方便多了。在Oracle Spatial中,基於R樹的空間索引採用的就是這種方法(這也是推薦的索引演算法),這個矩形叫MBR:Minimum Bounding Rectangle。
圖 4 Oracle Spatial中幾何對象的MBR
在Oracle Spatial中,一個空間表裡所有的幾何對象就是通過它們的MBR的R樹索引進行管理的,從下面的圖中很容易可以理解,MBR索引的根節點包括A、B兩個較大的MBR,當一個查詢可以很快速地找到A後,再尋找其中的a或b這兩個比較小的MBR,如果找到了a,那麼再最終找到1或者2這兩個最小的MBR。
圖 5 R樹索引的MBR
對於上面我們建立過索引的測試表TEST_INDEX來說,他的MBR的索引相關資訊存放在USER_SDO_INDEX_METADATA視圖中:
SQL> select sdo_index_table,SDO_RTREE_HEIGHT,SDO_RTREE_NUM_NODES from user_sdo_index_metadata where sdo_index_name='IDX_TEST_INDEX_GEOM';
SDO_INDEX_TABLE SDO_RTREE_HEIGHT SDO_RTREE_NUM_NODES
----------------------------- ------------------------- ---------------------------------
MDRT_1350B$ 4 3336
如果我們開啟一下MDRT_1350B$這張表,你可以看到裡面儲存著R樹中每個節點的資訊:
SQL> desc mdrt_1350B$
名稱 是否為空白? 類型
----------------------------------------------------------------- -------- --------------------------------------------
NODE_ID NUMBER
NODE_LEVEL NUMBER
INFO BLOB
SQL> select * from mdrt_1350B$ where node_level=3 and rownum<3;
NODE_ID NODE_LEVEL
---------- ----------
INFO
------------------------------------------------------------------------------------------------------------------------
3336 3
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000001F000000080D0000
0000000041414154554D414147414141426F6F41
3337 3
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000001F000000090D0000
0000000041414154554D414147414141426F5241
2. 四叉樹空間索引
Oracle Spaital並不鼓勵使用四叉樹空間索引,除非某些特殊情境並且你確認採用四叉樹索引會帶來好處[1]
。Oracle提供了一個表格對比了R樹空間索引和四叉樹空間索引的一些特點。
R 樹 |
四叉樹 |
不能很好地近似幾何對象(MBR對奇形怪狀的幾何對象的近似比較粗略) |
可以較好地近似幾何對象 |
索引建立和調整比較簡單 |
索引調整較複雜,而且索引的參數對效能影響較大 |
儲存空間較小 |
儲存空間較大 |
SDO_NN操作較快,同時還可以指定操作的SDO_BATCH_SIZE參數 |
相反 |
大批次更新資料時可能會降低空間表的訪問效率 |
資料更新於訪問效率無關 |
可以對4個維度進行索引 |
只能索引2個維度 |
對於地理座標系的資料,並會使用到SDO_WITHIN_DISTANCE操作時,建議使用R樹索引 |
相反 |
對於whole-Earth資料[2] 只能使用R樹索引 |
相反 |
四叉樹空間索引的原理像地圖切片的原理, 6,可以想象,分級的層級越多,對幾何對象的描述會更準確。
圖
6 Oracle Spatial四叉樹空間索引
一般在Oracle Spatial建立四叉樹空間索引採用固定切片範圍的方式,這種方式根據當前的地圖範圍和SDO_LEVEL參數的設定,如果SDO_LEVEL為1,那就相當於整個圖層一個切片;如果SDO_LEVEL為2,則整個圖層等分為4塊;依次類推。另外,在四叉樹索引中,幾何對象的每個Element都會被索引, 7。
圖
7 四叉樹空間索引中幾何對象的Element
通過如下的方式可以建立一個固定切片大小、8級深度的四叉樹空間索引:
SQL> create index idx_continent_geom on spatial.continent(geom) indextype is mdsys.spatial_index parameters('SDO_LEVEL=8');
索引已建立。
經過時間: 00: 05: 11.48
SQL> select sdo_index_type,sdo_index_table from user_sdo_index_metadata where sdo_index_name='IDX_CONTINENT_GEOM';
SDO_INDEX_TYPE
------------------------------------------------------------------------------------------------
SDO_INDEX_TABLE
------------------------------------------------------------------------------------------------
QTREE
MDQT_13537$
這裡存放索引資料的表名字叫MDQT_13537$,可以查看這個表的結構和R樹索引的表已經完全不同了:
SQL> desc MDQT_13537$
名稱 是否為空白? 類型
----------------------------------------------------------------- -------- --------------------------------------------
SDO_CODE RAW(16)
SDO_ROWID ROWID
SDO_STATUS VARCHAR2(1)
SQL> select * from MDQT_13537$ where rownum<10;
SDO_CODE SDO_ROWID SDO_STATUS
-------------------------------------- ------------------------------- ----------------
CBD9 AAATUWAAGAAABNGAAA B
CBDC AAATUWAAGAAABNGAAA B
CBDD AAATUWAAGAAABNGAAA I
CBDE AAATUWAAGAAABNGAAA B
CBDF AAATUWAAGAAABNGAAA B
CC00 AAATUWAAGAAABNGAAA I
CC01 AAATUWAAGAAABNGAAA I
CC02 AAATUWAAGAAABNGAAA I
CC03 AAATUWAAGAAABNGAAA I
其中SDO_STATUS的值如果是B表示幾何對象和當前的切片邊界相交;如果是I表示幾何對象在當前切片之內。
[1]
《Oracle Spatial Quadtree Indexing》:The use of spatial quadtree indexes is discouraged. You are strongly encouraged to use R-tree indexing for spatial indexes, unless you need to continue using quadtree indexes for special situations.
[2]
Oracle Spatial中包含一個whole-Earth幾何模型,可以直接在地理座標系的資料上根據地球表面曲率等參數進行真實長度、面積的計算,類似內建的投影演算法