$ time db2se import_shape testdb -fileName /home/stolze/europe/roads
-srsName WGS84_SRS_1003 -tableName roads -createTableFlag 1
-spatialColumn shape -typeName ST_LineString -idColumn id
-commitScope 1500 -messagesFile /home/stolze/import.msg
GSE0000I The Operation was completed successfully.
real
2m19.086s
user 0m0.050s
sys 0m0.021s
$ db2batch -d testdb -f test_config_advisor.sql -i complete -s on
---------------------------------------------
Statement number: 1
SELECT id
FROM roads
WHERE db2gse.ST_Intersects(shape, db2gse.ST_LineString(
'linestring(10 50, 20 40)', 1003)) = 1
PRepare Time is: 0.000 seconds
Execute Time is: 1.248 seconds
Fetch Time is: 0.000 seconds
Elapsed Time is: 1.248 seconds
---------------------------------------------
Statement number: 2
CREATE INDEX roads_grid_index ON roads(shape)
EXTEND USING db2gse.spatial_index(0.27, 0.54, 1.6)
Elapsed Time is: 25.503 seconds
---------------------------------------------
上一頁12345678下一頁 注重,測試系統使用的配置是次優的,因為導入的數據是從與數據庫和數據庫日志在同一個硬盤驅動器上的文件中讀取的。因而,讀操作與日志寫和緩沖池中的數據頁的寫操作之間存在競爭??赡苄枰獙⒏鞣N特定于磁盤的任務分配到不同的文件系統上。當使用 DB2 Spatial Extender 導入工具導入 shapefile 文件時,建議不要嘗試直接從 CD 裝載數據,而是先將它復制到一個硬盤上。CD-ROM 驅動器不是很適合讀 shapefile 文件的訪問模式,因此整個操作的速度會急劇降慢。 在應用了 Configuration Advisor 的建議之后,重復前面列出的步驟就產生了清單 2 中的結果??梢钥吹?,僅僅是導入操作的性能就提高了 11%,查詢的速度快了 28%,甚至創建索引所花的時間也只有之前的 90%。所以不應當忽視最基本的性能調優?! ∏鍐?2. 調優后的數據庫上的空間操作$ time db2se import_shape testdb -fileName /home/stolze/europe/roads
-srsName WGS84_SRS_1003 -tableName roads -createTableFlag 1
-spatialColumn shape -typeName ST_LineString -idColumn id
-commitScope 1500 -messagesFile /home/stolze/import.msg
GSE0000I The operation was completed successfully.
real
2m2.848s
user 0m0.051s
sys 0m0.027s
$ db2batch -d testdb -f test_config_advisor.sql -i complete -s on
---------------------------------------------
Statement number: 1
SELECT id
FROM roads
WHERE db2gse.ST_Intersects(shape, db2gse.ST_LineString(
'linestring(10 50, 20 40)', 1003)) = 1
Prepare Time is: 0.000 seconds
Execute Time is: 0.895 seconds
Fetch Time is: 0.000 seconds
Elapsed Time is: 0.895 seconds
---------------------------------------------
Statement number: 2
CREATE INDEX roads_grid_index ON roads(shape)
EXTEND USING db2gse.spatial_index(0.27, 0.54, 1.6)
Elapsed Time is: 22.980 seconds
---------------------------------------------
上一頁123456789下一頁 DB2 內部對空間數據的處理 空間數據可能變得非常復雜,需要很多空間來存儲一個幾何圖形中各個點的信息。例如,表示整個美國的區域的幾何圖形由 60 個多邊形組成,總共有 198569 個點來定義那些多邊形。按照 Spatial Extender 內部格式,這個幾何圖形的完整定義要使用 0.9 MB 的磁盤空間(使用了壓縮)。假如幾何圖形按照 ESRI 幾何圖形格式編碼,那么它實際上需要 3.1 MB 的磁盤空間(請參閱 參考資料 一節,了解關于 ESRI 幾何圖形格式的更多信息)。所有信息封裝在一個 ST_Geometry 值中,這意味著這個值在數據庫中也需要大約 1 MB 的磁盤空間。另一個例子是只表示一個點的空間值。對于 X 和 Y 維,我們只有用于兩個浮點值的 8 個字節。將一個點表示成 ST_Point 值會增加一些開銷,但是我們談論時仍然當作是幾個字節?! B2 表中一個行中存儲的所有值的總大小不能超過表空間的頁寬。一個例外是大型對象(LOB),它最大可達 2 GB。DB2 支持的最大頁寬是 32K。所以存儲需要 1 MB 空間的幾何圖形需要類似于 LOB 的存儲機制。但總是為點數據使用那種機制就過分了。為了解決千差萬別的需求,DB2 實現了一種用于存儲空間數據(或通常的結構數據)的混合方法。假如一個空間值超過了某個大?。此^的 inline length),那么這個值就被存儲為 BLOB。否則,這個值就存儲為 VARCHAR FOR BIT DATA 值。下一節 將具體討論如何為空間列設置 inline length,以及通過更改設置可以獲得的好處。之后,我們討論 空間數據聚集,為 編寫空間 SQL 查詢、調優 空間網格索引 提供指南,最后我們解釋假如經常要修改數據,則建議使用哪種 表空間類型?! ≡O置空間列的 inline length 在 上一節 中,我們解釋了 DB2 存儲需求多變的空間數據的內部機制。確定幾何圖形是存儲為 VARCHAR FOR BIT DATA 還是 BLOB 的決定因素就是所謂的 inline length,這個參數適用于任何表中的空間列。假如空間值的內部表示需要的字節數少于 inline length 設置中指定的值,那么它將以 內聯(inline) 的方式存儲為 VARCHAR FOR BIT DATA。否則,這個值將被 大對象化(lobify),并在該表的 LONG 表空間中存儲為 LOB。 上一頁12345678910下一頁 應該記住,以內聯方式存儲數據比以大對象化方式存儲數據要可取得多。原因是,內聯的數據當作 VARCHAR FOR BIT DATA 對待。這個值與同一行中所有其他屬性一起存儲在一個數據頁中。一旦數據存儲在那樣一個頁上,那一頁將通過緩沖池來訪問,這樣可以利用先進的緩存技術,從而盡量避免文件 I/O。而對于 LOB 則截然不同,它總是直接從磁盤讀取。 所以經驗法則非常簡單:將 inline length 設置得盡可能高,以便讓盡可能多的空間值以內聯方式存儲。當然,實際情況并不像看上去的那么簡單。高的 inline length 值告訴 DB2 空間值實際上可以在單獨一行中占用很多字節。每一行的最大大小要受到針對表定義的頁寬和屬性(列)的限制。例如,假如有一個頁寬為 4 KB(4096)的表空間,那么一行的最大大小不能超過 4005 字節(請參閱 參考資料 一節,了解關于 SQL 限制的更多信息)。假如這個表有一個不能為空的 INTEGER 列和一個可以為空的 VARCHAR(100) 列,再加上一個空間列,那么最多可以將 inline length 設置為 4005 - 6 - 4 - (1+2+100) - 1 = 3891,其中 6 個字節用于行的前綴,4 個字節是 INTEGER 列需要的空間,(1+2+100) 個字節是為 VARCHAR(100) 預留的,最后 1 個字節用于空間列的 NULL 指示符(請參閱 參考資料 一節,找到關于數據庫對象和 CREATE TABLE 語句的一本書)。可以看到,其他列的長度和 inline length 實際上是相互競爭的。為了進一步增加 inline length,可以將表放在頁寬為 8K、16K 甚至 32K 的表空間上。這樣,對于之前的例子,就可以分別將 inline length 設為 7987、16179 或 32563 字節?! nline length 當在數據庫中創建一個新的結構類型時,DB2 將根據類型定義中指定的屬性計算那個數據類型的缺省 inline length??梢栽谙到y編目視圖 SYSCAT.DATATYPES 的 INLINE_LENGTH 列上找到一個結構類型的缺省 inline length。假如在 CREATE TABLE 或 ALTER TABLE ... ADD COLUMN ... 語句中定義表的列時沒有顯式地指定 inline length,那么將沿用缺省值。 上一頁234567891011下一頁 可以使用 ALTER TABLE ... ALTER COLUMN ... SET INLINE LENGTH ... 語句修改(增加)已有空間列的 inline length。除非通過 REORG TABLE 語句 加 LONGLOBDATA 選項重組存儲在表中的數據,否則這種修改只影響 DB2 編目和隨后的數據修改。假如值的大小小于新的 inline length,那么這個重組過程將把大對象化的空間值轉換成內聯值。 選擇適當的 inline length 在將所有空間數據存儲到 32K 的表空間上并且將 inline length 設置成盡可能大的值之前,應該首先分析您的數據實際上有多大以及其他參數可能對頁寬產生的影響。假如只有 ST_Point 值,那么每個點將需要最多 245 字節的物理存儲,如清單 3 所示。在這種情況下,甚至 減少 inline length 更有幫助,因為可以使用更小的頁寬和/或在表中使用更多的列。但是要注重,ALTER TABLE 語句只答應增加 inline length。假如想使用更小的值,那么必須在創建表的時候指定。Spatial Extender 導入過程答應顯式地為空間列指定 inline length?! ≡诮Y構類型中嵌套 LOB 雖然 points 屬性被定義為 BLOB,但是 DB2 并不會單獨地存儲它。相反,整個幾何圖形信息(包括 BLOB 數據)都存儲在一起 —— 至于存儲為內聯值還是大對象化值,則取決于列的 inline length。結構類型的實現使所有屬性值并置到一個二進制流中,任何添加的必要的元信息和產生的二進制流在物化(也就是存儲到一個表中)的時候,或者存儲為內聯值,或者存儲為大對象化值?! ∵@種方法使任何處理 LOB 的應用程序可以以內聯方式存儲短的 LOB 值,并利用 DB2 的緩沖池。 清單 3 展示了如何計算每個幾何圖形在以內聯方式存儲時需要多少磁盤空間。我們假設所有幾何圖形都存儲在一個名為 SPATIAL_DATA 的表的 GEOMETRY 列中。第一個查詢使用 LENGTH 函數。該函數顯示以內聯方式存儲的值的寬度。假如是大對象化的值,那么它顯示引用實際值的定位符的寬度。所以只有知道所有空間值都是內聯值時,才可以放心地使用該函數。因此,下面的查詢根據空間數據類型的屬性來計算數據的寬度。關于屬性的信息可以從 DB2 編目視圖 SYSCAT.DATATYPES 和 SYSCAT.ATTRIBUTES 獲得。假如空間數據是使用結構類型實現的,那么在 SQL Reference 中關于 CREATE TYPE 語句的解釋中提到的判定結構類型值寬度的法則同樣適用(請參閱 參考資料 一節,了解關于 CREATE TYPE 語句的信息)。具體地說,ST_Geometry 類型定義 16 個屬性,它的子類型都沒有添加自己的屬性。除了三個屬性外,所有屬性都是所謂的 短屬性。其中兩個非短屬性 anno_text 和 ext 沒有被使用,第三個非短屬性 points 包含內部編碼為 BLOB 的幾何圖形信息。除了實際的數據外,DB2 需要維護強制的 null 指示符(1 個字節)和長度信息(4 個字節)。因此,幾何圖形的大小可以通過公式 “32 + 16*10 + 5 + LENGTH(points) = 197 + LENGTH(points)” 得出。 上一頁3456789101112下一頁 清單 3. 幾何圖形的空間需求-- maximum space requirement for spatial point data
CREATE TABLE test ( p db2gse.ST_Point INLINE LENGTH 3800 )@
INSERT INTO test VALUES ( db2gse.ST_Point(
1234567890123456, 1234567890123456,
1234567890123456, 1234567890123456, 0) )@
SELECT LENGTH(p) FROM test@
1
-----------
245
1 record(s) selected.
-- determining the size of all geometries in a table
SELECT 197 + LENGTH(geometry..points)
FROM spatial_data@
-- calculating #geometries that would be stored inline/lobified
-- for a given inline length
SELECT SUM(inline) AS inline, COUNT(*) - SUM(inline) AS lobified
FROM ( SELECT CASE
WHEN 197 + LENGTH(geometry..points) <= <inline_length>
THEN 1
ELSE 0
END
FROM spatial_data ) AS t(inline)@
性能比較 為了演示小的 inline length 與大的 inline length 的效果,我們首先將 shapefile 文件 europe/roads.shp 導入到一個 inline length 為 292 的表中。這是 DB2 答應的最小值。接著運行一個 SQL 腳本,該腳本確定有多少幾何圖形以內聯方式存儲,有多少幾何圖形必須以大對象化的方式存儲。然后測量執行一個簡單空間查詢的時間,并顯示在執行期間產生的語句快照的一個摘錄,以揭示影響性能的最突出的因素。整個過程在 inline length 為 2000 的情況下再重復一遍,2000 這個值足以導致那個 shapefile 文件中的所有幾何圖形都以內聯方式存儲。下載 一節中包含了我們運行 db2batch 時使用的腳本 test_inline_length.sql。 上一頁45678910111213下一頁 清單 4. 不同 inline length 設置的效果$ time db2se import_shape testdb -fileName /home/stolze/europe/roads
-srsName WGS84_SRS_1003 -tableName roads -createTableFlag 1
-spatialColumn shape -typeName ST_LineString -inlineLength 292
-idColumn id -commitScope 1500
GSE0000I The operation was completed successfully.
real
3m15.604s
user 0m0.050s
sys 0m0.026s
$ db2batch -d testdb -f test_inline_length.sql -i complete -s on
---------------------------------------------
Statement number: 1
SELECT SUM(inline) AS inline_storage,
COUNT(*) - SUM(inline) AS lobified_storage
FROM ( SELECT CASE
WHEN 197 + LENGTH(shape..points) <=
( SELECT inline_length
FROM syscat.columns
WHERE colname = 'SHAPE' AND
tabname = 'ROADS' )
THEN 1
ELSE 0
END
FROM roads ) AS t(inline)
INLINE_STORAGE LOBIFIED_STORAGE
-------------- ----------------
89595 21384
---------------------------------------------
Statement number: 2
SELECT id
FROM roads
WHERE db2gse.ST_Intersects(shape, db2gse.ST_LineString(
'linestring(10 50, 20 40)', 1003)) = 1
Prepare Time is: 0.000 seconds
Execute Time is: 0.854 seconds
Fetch Time is: 0.000 seconds
Elapsed Time is: 0.855 seconds
Buffer pool data logical reads = 16818
Buffer pool index logical reads = 19731
Direct reads = 3088
Direct read requests = 1544
Direct read elapsed time (ms) = 18
---------------------------------------------
$ db2 "DROP TABLE roads"
$ time db2se import_shape testdb -fileName /home/stolze/europe/roads
-srsName WGS84_SRS_1003 -tableName roads -createTableFlag 1
-spatialColumn shape -typeName ST_LineString -inlineLength 2000
-idColumn id -commitScope 1500
GSE0000I The operation was completed successfully.
real
1m57.212s
user 0m0.049s
sys 0m0.027s
$ db2batch -d testdb -f test_inline_length.sql -i complete -s on
---------------------------------------------
Statement number: 1
SELECT SUM(inline) AS inline_storage,
COUNT(*) - SUM(inline) AS lobified_storage
FROM ( SELECT CASE
WHEN 197 + LENGTH(shape..points) <=
( SELECT inline_length
FROM syscat.columns
WHERE colname = 'SHAPE' AND
tabname = 'ROADS' )
THEN 1
ELSE 0
END
FROM roads ) AS t(inline)
INLINE_STORAGE LOBIFIED_STORAGE
-------------- ----------------
110979 0
---------------------------------------------
Statement number: 2
SELECT id
FROM roads
WHERE db2gse.ST_Intersects(shape, db2gse.ST_LineString(
'linestring(10 50, 20 40)', 1003)) = 1
Prepare Time is: 0.000 seconds
Execute Time is: 0.792 seconds
Fetch Time is: 0.000 seconds
Elapsed Time is: 0.792 seconds
Buffer pool data logical reads = 17337
Buffer pool index logical reads = 19731
Buffer pool index physical reads = 0
Direct reads = 2
Direct read requests = 1
Direct read elapsed time (ms) = 0
---------------------------------------------
上一頁567891011121314下一頁 從結果中可以看出,對于重要操作,較大的 inline length 可以增加 40% 的速度,對樣本數據的查詢也快了 7%。這兩種差異的底層原因是,當使用較小的 inline length 時,有超過 20000 個幾何圖形(大約 20% 的數據)以大對象化的方式存儲。DB2 直接從磁盤讀(寫) LOB 數據。而在第二種場景中,大部分的直接讀是不需要的,因為可以用存儲在緩沖池中的內聯數據來滿足查詢。注重,大對象化的數據所占的 20% 的比例實際上不算很壞。假如由于稍微復雜一點兒的幾何圖形導致更多的數據不能以內聯方式存儲,那么這里演示的差異還要大大增加?! 【奂臻g數據 根據某個屬性聚集數據是一種常見的、也是非常有用的技術,這種技術可以物理地組織一個表的數據。通過對底層的觀察可以發現,具有相似值的數據經常一起被訪問。所以,可以將類似的數據存儲在接近的位置,使得對那些數據的訪問不必分散到表空間中很多不同的頁上,而是分布在臨近的幾個頁上。根據空間數據的空間屬性或幾何圖形間的距離聚集空間數據是很自然的。空間查詢是展示局部數據訪問(換句話說,現實中臨近的幾何圖形經常被一起訪問)的最好例子之一。例如,假如您看一個城市的街道地圖,那么很可能對那個城市的所有街道感愛好,而對地區另一邊某個其他城市的街道不感愛好。所以在物理上將那個城市的一些行存儲在相鄰的位置的確很有意義。 在 DB2 中建立數據聚集屬性的方法是根據一個索引對表進行重組。然而,假如由于空間索引的復雜性質導致 DB2 REORG TABLE 命令不理解空間索引,事情就不會那么輕易了。關于這個問題有一個輕易的方法,即使用一個列,這個列的值是根據涉及的圖形計算的。這個列上聲明的數據類型必須保證 DB2 能在這個列上創建一個本地 B- 樹索引。這里使用空間填充曲線來保存空間和拓撲屬性(請參閱 參考資料 一節,找到 H. Sagan 撰寫的書籍)。我們在幾何圖形上取一個點,即形心點, 計算那個點在空間填充曲線上的值,并將結果存儲在一個附加的列中。最后,在附加列上創建一個索引,并根據那個索引對表進行重組。 上一頁6789101112131415下一頁 新聞熱點
疑難解答