一些補充測試結果:
1. 幾何對象的儲存空間
為了測試Oracle Spatial和ArcSDE在相對真實的環境中幾何Object Storage Service空間的大小,測試分別使用了2個包含約1億個要素的線資料和面資料進行。其中線資料只包含幾何資訊,面資料還包含一些屬性資訊。大部分線資料只包含2個節點,而面資料一般都是幾十個節點以上
對這2個資料分別進行了儲存空間的比較:
資料 |
儲存類型 |
空間資料表格儲存體大小(G) |
線資料 |
ST_GEOMETRY |
14.72 |
SDO_ GEOMETRY |
16.51 |
面資料 |
ST_ GEOMETRY |
49.93 |
SDO_ GEOMETRY |
87.87 |
可見隨著幾何對象節點數的增加,SDO_Geometry儲存耗費的空間要多不少。
· 空間索引的效能
1. 空間索引的用處
對於空間資料庫進行空間查詢的操作一般都有兩個階段,對於Oracle Spatial而言,一個空間查詢分為2個步驟,一個稱為主過濾(Primary Filter),另外一個稱為次過濾(Secondary Filter)。主過濾通過矩形的MBR相交從海量的資料中首先過濾出可能符合空間查詢的一小部分資料,然後再用次過濾中具體的空間關係演算法來判斷這個小的結果集中到底哪些是滿足空間關係的。 12,在主過濾的過程中,空間索引會被使用到。
圖
12 Oracle Spatial中空間查詢的處理流程
對於ArcSDE來說,原理上也是類似,ArcSDE中有一個函數叫ST_ENVINTERSECTS,這就是通過四角座標來從海量資料中過濾一個矩形範圍內的一小部分資料。對於其它一般的空間操作,比如ST_WITHIN等,只要你的資料建立了空間索引,這個操作也會先通過空間索引找到一個小資料集(相當於ST_ENVINTERSECTS操作,或者說Oracle Spatial中的主過濾),然後再通過具體的“Within”的空間關係演算法再查得準確的結果(相當於Oracle Spatial中的次過濾)。當然,如果資料沒有空間索引,那麼上面的操作就沒有空間索引可用,不過ArcSDE也能查到結果,這比Oracle Spatial不建空間索引就不能作空間查詢要好一些。
2. 主過濾/ST_ENVINTERSECTS的比較
因此,從上一小節可以知道,空間索引的效率可以通過Oracle Spatial中的“主過濾”和ArcSDE的ST_ENVINTERSECTS的比較得到一個參考的結果。
以下是對上面使用過的約1億條資料的線資料和面資料分別進行SQL語句查詢的效能。測試代碼如下:
public class PerformanceTest {
public static void main(String[] args) {
PerformanceTest test = new PerformanceTest();
test.execute();
}
private static final String url = "jdbc:oracle:thin:@192.168.200.224:1521:test";
private static final String user = "sde";
private static final String password = "sde";
public void execute() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);
String sql = "select shape from sdo_test.streets where sdo_filter(shape,SDO_GEOMETRY(2003,NULL,NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-72.527,41.869,-72.493,41.869,-72.493,41.891,-72.527,41.891,-72.527,41.869)))='TRUE'";
long start = System.currentTimeMillis();
stmt = conn.prepareStatement(sql);
stmt.setFetchSize(1000);
int count = 0;
rs = stmt.executeQuery();
while (rs.next()) {
Object shape = rs.getObject(1);//讀取幾何對象值
count ++;
}
long end = System.currentTimeMillis();
System.out.println("查詢結果:" + count);
System.out.println("查詢時間:" + (end - start) + "ms");
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try {
rs.close();
} catch (SQLException e) {
}
try {
stmt.close();
} catch (SQLException e) {
}
try {
conn.close();
} catch (SQLException e) {
}
}
}
}
線資料測試結果,耗時單位為秒,每種類型分別對應前後兩個結果分別代表在資料庫中沒有資料區塊緩衝和緩衝後的結果:
查詢範圍(真實結果數) |
ST_GEOMETRY |
SDO_ GEOMETRY |
範圍約10個要素(8) |
0.357 0.156 |
0.218 0.203 |
|
|
範圍約100個要素(114) |
0.734 0.203 |
0.811 0.203 |
|
|
範圍約1000個要素(1341) |
0.920 0.250 |
0.951 0.234 |
|
|
範圍約10000個要素(10414) |
2.386 0.562 |
3.104 0.400 |
|
|
面資料測試結果,耗時單位為秒,每種類型分別對應前後兩個結果分別代表在資料庫中沒有資料區塊緩衝和緩衝後的結果:
查詢範圍(真實結果數) |
ST_ GEOMETRY |
SDO_ GEOMETRY |
範圍約10個要素(16) |
0.530 0.160 |
0.780 0.203 |
|
|
範圍約100個要素(133) |
2.636 0.343 |
1.841 0.220 |
|
|
範圍約1000個要素(1104) |
8.034 0.500 |
8.517 0.300 |
|
|
範圍約10000個要素(10494) |
29.952 1.310 |
43.010 0.950 |
|
|