$ 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
---------------------------------------------
上一頁(yè)12345678下一頁(yè) 注重,測(cè)試系統(tǒng)使用的配置是次優(yōu)的,因?yàn)閷?dǎo)入的數(shù)據(jù)是從與數(shù)據(jù)庫(kù)和數(shù)據(jù)庫(kù)日志在同一個(gè)硬盤驅(qū)動(dòng)器上的文件中讀取的。因而,讀操作與日志寫和緩沖池中的數(shù)據(jù)頁(yè)的寫操作之間存在競(jìng)爭(zhēng)。可能需要將各種特定于磁盤的任務(wù)分配到不同的文件系統(tǒng)上。當(dāng)使用 DB2 Spatial Extender 導(dǎo)入工具導(dǎo)入 shapefile 文件時(shí),建議不要嘗試直接從 CD 裝載數(shù)據(jù),而是先將它復(fù)制到一個(gè)硬盤上。CD-ROM 驅(qū)動(dòng)器不是很適合讀 shapefile 文件的訪問(wèn)模式,因此整個(gè)操作的速度會(huì)急劇降慢。 在應(yīng)用了 Configuration Advisor 的建議之后,重復(fù)前面列出的步驟就產(chǎn)生了清單 2 中的結(jié)果。可以看到,僅僅是導(dǎo)入操作的性能就提高了 11%,查詢的速度快了 28%,甚至創(chuàng)建索引所花的時(shí)間也只有之前的 90%。所以不應(yīng)當(dāng)忽視最基本的性能調(diào)優(yōu)。 清單 2. 調(diào)優(yōu)后的數(shù)據(jù)庫(kù)上的空間操作$ 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
---------------------------------------------
上一頁(yè)123456789下一頁(yè) DB2 內(nèi)部對(duì)空間數(shù)據(jù)的處理 空間數(shù)據(jù)可能變得非常復(fù)雜,需要很多空間來(lái)存儲(chǔ)一個(gè)幾何圖形中各個(gè)點(diǎn)的信息。例如,表示整個(gè)美國(guó)的區(qū)域的幾何圖形由 60 個(gè)多邊形組成,總共有 198569 個(gè)點(diǎn)來(lái)定義那些多邊形。按照 Spatial Extender 內(nèi)部格式,這個(gè)幾何圖形的完整定義要使用 0.9 MB 的磁盤空間(使用了壓縮)。假如幾何圖形按照 ESRI 幾何圖形格式編碼,那么它實(shí)際上需要 3.1 MB 的磁盤空間(請(qǐng)參閱 參考資料 一節(jié),了解關(guān)于 ESRI 幾何圖形格式的更多信息)。所有信息封裝在一個(gè) ST_Geometry 值中,這意味著這個(gè)值在數(shù)據(jù)庫(kù)中也需要大約 1 MB 的磁盤空間。另一個(gè)例子是只表示一個(gè)點(diǎn)的空間值。對(duì)于 X 和 Y 維,我們只有用于兩個(gè)浮點(diǎn)值的 8 個(gè)字節(jié)。將一個(gè)點(diǎn)表示成 ST_Point 值會(huì)增加一些開銷,但是我們談?wù)摃r(shí)仍然當(dāng)作是幾個(gè)字節(jié)。 DB2 表中一個(gè)行中存儲(chǔ)的所有值的總大小不能超過(guò)表空間的頁(yè)寬。一個(gè)例外是大型對(duì)象(LOB),它最大可達(dá) 2 GB。DB2 支持的最大頁(yè)寬是 32K。所以存儲(chǔ)需要 1 MB 空間的幾何圖形需要類似于 LOB 的存儲(chǔ)機(jī)制。但總是為點(diǎn)數(shù)據(jù)使用那種機(jī)制就過(guò)分了。為了解決千差萬(wàn)別的需求,DB2 實(shí)現(xiàn)了一種用于存儲(chǔ)空間數(shù)據(jù)(或通常的結(jié)構(gòu)數(shù)據(jù))的混合方法。假如一個(gè)空間值超過(guò)了某個(gè)大小(即所謂的 inline length),那么這個(gè)值就被存儲(chǔ)為 BLOB。否則,這個(gè)值就存儲(chǔ)為 VARCHAR FOR BIT DATA 值。下一節(jié) 將具體討論如何為空間列設(shè)置 inline length,以及通過(guò)更改設(shè)置可以獲得的好處。之后,我們討論 空間數(shù)據(jù)聚集,為 編寫空間 SQL 查詢、調(diào)優(yōu) 空間網(wǎng)格索引 提供指南,最后我們解釋假如經(jīng)常要修改數(shù)據(jù),則建議使用哪種 表空間類型。 設(shè)置空間列的 inline length 在 上一節(jié) 中,我們解釋了 DB2 存儲(chǔ)需求多變的空間數(shù)據(jù)的內(nèi)部機(jī)制。確定幾何圖形是存儲(chǔ)為 VARCHAR FOR BIT DATA 還是 BLOB 的決定因素就是所謂的 inline length,這個(gè)參數(shù)適用于任何表中的空間列。假如空間值的內(nèi)部表示需要的字節(jié)數(shù)少于 inline length 設(shè)置中指定的值,那么它將以 內(nèi)聯(lián)(inline) 的方式存儲(chǔ)為 VARCHAR FOR BIT DATA。否則,這個(gè)值將被 大對(duì)象化(lobify),并在該表的 LONG 表空間中存儲(chǔ)為 LOB。 上一頁(yè)12345678910下一頁(yè) 應(yīng)該記住,以內(nèi)聯(lián)方式存儲(chǔ)數(shù)據(jù)比以大對(duì)象化方式存儲(chǔ)數(shù)據(jù)要可取得多。原因是,內(nèi)聯(lián)的數(shù)據(jù)當(dāng)作 VARCHAR FOR BIT DATA 對(duì)待。這個(gè)值與同一行中所有其他屬性一起存儲(chǔ)在一個(gè)數(shù)據(jù)頁(yè)中。一旦數(shù)據(jù)存儲(chǔ)在那樣一個(gè)頁(yè)上,那一頁(yè)將通過(guò)緩沖池來(lái)訪問(wèn),這樣可以利用先進(jìn)的緩存技術(shù),從而盡量避免文件 I/O。而對(duì)于 LOB 則截然不同,它總是直接從磁盤讀取。 所以經(jīng)驗(yàn)法則非常簡(jiǎn)單:將 inline length 設(shè)置得盡可能高,以便讓盡可能多的空間值以內(nèi)聯(lián)方式存儲(chǔ)。當(dāng)然,實(shí)際情況并不像看上去的那么簡(jiǎn)單。高的 inline length 值告訴 DB2 空間值實(shí)際上可以在單獨(dú)一行中占用很多字節(jié)。每一行的最大大小要受到針對(duì)表定義的頁(yè)寬和屬性(列)的限制。例如,假如有一個(gè)頁(yè)寬為 4 KB(4096)的表空間,那么一行的最大大小不能超過(guò) 4005 字節(jié)(請(qǐng)參閱 參考資料 一節(jié),了解關(guān)于 SQL 限制的更多信息)。假如這個(gè)表有一個(gè)不能為空的 INTEGER 列和一個(gè)可以為空的 VARCHAR(100) 列,再加上一個(gè)空間列,那么最多可以將 inline length 設(shè)置為 4005 - 6 - 4 - (1+2+100) - 1 = 3891,其中 6 個(gè)字節(jié)用于行的前綴,4 個(gè)字節(jié)是 INTEGER 列需要的空間,(1+2+100) 個(gè)字節(jié)是為 VARCHAR(100) 預(yù)留的,最后 1 個(gè)字節(jié)用于空間列的 NULL 指示符(請(qǐng)參閱 參考資料 一節(jié),找到關(guān)于數(shù)據(jù)庫(kù)對(duì)象和 CREATE TABLE 語(yǔ)句的一本書)。可以看到,其他列的長(zhǎng)度和 inline length 實(shí)際上是相互競(jìng)爭(zhēng)的。為了進(jìn)一步增加 inline length,可以將表放在頁(yè)寬為 8K、16K 甚至 32K 的表空間上。這樣,對(duì)于之前的例子,就可以分別將 inline length 設(shè)為 7987、16179 或 32563 字節(jié)。 inline length 當(dāng)在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)新的結(jié)構(gòu)類型時(shí),DB2 將根據(jù)類型定義中指定的屬性計(jì)算那個(gè)數(shù)據(jù)類型的缺省 inline length。可以在系統(tǒng)編目視圖 SYSCAT.DATATYPES 的 INLINE_LENGTH 列上找到一個(gè)結(jié)構(gòu)類型的缺省 inline length。假如在 CREATE TABLE 或 ALTER TABLE ... ADD COLUMN ... 語(yǔ)句中定義表的列時(shí)沒(méi)有顯式地指定 inline length,那么將沿用缺省值。 上一頁(yè)234567891011下一頁(yè) 可以使用 ALTER TABLE ... ALTER COLUMN ... SET INLINE LENGTH ... 語(yǔ)句修改(增加)已有空間列的 inline length。除非通過(guò) REORG TABLE 語(yǔ)句 加 LONGLOBDATA 選項(xiàng)重組存儲(chǔ)在表中的數(shù)據(jù),否則這種修改只影響 DB2 編目和隨后的數(shù)據(jù)修改。假如值的大小小于新的 inline length,那么這個(gè)重組過(guò)程將把大對(duì)象化的空間值轉(zhuǎn)換成內(nèi)聯(lián)值。 選擇適當(dāng)?shù)?inline length 在將所有空間數(shù)據(jù)存儲(chǔ)到 32K 的表空間上并且將 inline length 設(shè)置成盡可能大的值之前,應(yīng)該首先分析您的數(shù)據(jù)實(shí)際上有多大以及其他參數(shù)可能對(duì)頁(yè)寬產(chǎn)生的影響。假如只有 ST_Point 值,那么每個(gè)點(diǎn)將需要最多 245 字節(jié)的物理存儲(chǔ),如清單 3 所示。在這種情況下,甚至 減少 inline length 更有幫助,因?yàn)榭梢允褂酶〉捻?yè)寬和/或在表中使用更多的列。但是要注重,ALTER TABLE 語(yǔ)句只答應(yīng)增加 inline length。假如想使用更小的值,那么必須在創(chuàng)建表的時(shí)候指定。Spatial Extender 導(dǎo)入過(guò)程答應(yīng)顯式地為空間列指定 inline length。 在結(jié)構(gòu)類型中嵌套 LOB 雖然 points 屬性被定義為 BLOB,但是 DB2 并不會(huì)單獨(dú)地存儲(chǔ)它。相反,整個(gè)幾何圖形信息(包括 BLOB 數(shù)據(jù))都存儲(chǔ)在一起 —— 至于存儲(chǔ)為內(nèi)聯(lián)值還是大對(duì)象化值,則取決于列的 inline length。結(jié)構(gòu)類型的實(shí)現(xiàn)使所有屬性值并置到一個(gè)二進(jìn)制流中,任何添加的必要的元信息和產(chǎn)生的二進(jìn)制流在物化(也就是存儲(chǔ)到一個(gè)表中)的時(shí)候,或者存儲(chǔ)為內(nèi)聯(lián)值,或者存儲(chǔ)為大對(duì)象化值。 這種方法使任何處理 LOB 的應(yīng)用程序可以以內(nèi)聯(lián)方式存儲(chǔ)短的 LOB 值,并利用 DB2 的緩沖池。 清單 3 展示了如何計(jì)算每個(gè)幾何圖形在以內(nèi)聯(lián)方式存儲(chǔ)時(shí)需要多少磁盤空間。我們假設(shè)所有幾何圖形都存儲(chǔ)在一個(gè)名為 SPATIAL_DATA 的表的 GEOMETRY 列中。第一個(gè)查詢使用 LENGTH 函數(shù)。該函數(shù)顯示以內(nèi)聯(lián)方式存儲(chǔ)的值的寬度。假如是大對(duì)象化的值,那么它顯示引用實(shí)際值的定位符的寬度。所以只有知道所有空間值都是內(nèi)聯(lián)值時(shí),才可以放心地使用該函數(shù)。因此,下面的查詢根據(jù)空間數(shù)據(jù)類型的屬性來(lái)計(jì)算數(shù)據(jù)的寬度。關(guān)于屬性的信息可以從 DB2 編目視圖 SYSCAT.DATATYPES 和 SYSCAT.ATTRIBUTES 獲得。假如空間數(shù)據(jù)是使用結(jié)構(gòu)類型實(shí)現(xiàn)的,那么在 SQL Reference 中關(guān)于 CREATE TYPE 語(yǔ)句的解釋中提到的判定結(jié)構(gòu)類型值寬度的法則同樣適用(請(qǐng)參閱 參考資料 一節(jié),了解關(guān)于 CREATE TYPE 語(yǔ)句的信息)。具體地說(shuō),ST_Geometry 類型定義 16 個(gè)屬性,它的子類型都沒(méi)有添加自己的屬性。除了三個(gè)屬性外,所有屬性都是所謂的 短屬性。其中兩個(gè)非短屬性 anno_text 和 ext 沒(méi)有被使用,第三個(gè)非短屬性 points 包含內(nèi)部編碼為 BLOB 的幾何圖形信息。除了實(shí)際的數(shù)據(jù)外,DB2 需要維護(hù)強(qiáng)制的 null 指示符(1 個(gè)字節(jié))和長(zhǎng)度信息(4 個(gè)字節(jié))。因此,幾何圖形的大小可以通過(guò)公式 “32 + 16*10 + 5 + LENGTH(points) = 197 + LENGTH(points)” 得出。 上一頁(yè)3456789101112下一頁(yè) 清單 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 導(dǎo)入到一個(gè) inline length 為 292 的表中。這是 DB2 答應(yīng)的最小值。接著運(yùn)行一個(gè) SQL 腳本,該腳本確定有多少幾何圖形以內(nèi)聯(lián)方式存儲(chǔ),有多少幾何圖形必須以大對(duì)象化的方式存儲(chǔ)。然后測(cè)量執(zhí)行一個(gè)簡(jiǎn)單空間查詢的時(shí)間,并顯示在執(zhí)行期間產(chǎn)生的語(yǔ)句快照的一個(gè)摘錄,以揭示影響性能的最突出的因素。整個(gè)過(guò)程在 inline length 為 2000 的情況下再重復(fù)一遍,2000 這個(gè)值足以導(dǎo)致那個(gè) shapefile 文件中的所有幾何圖形都以內(nèi)聯(lián)方式存儲(chǔ)。下載 一節(jié)中包含了我們運(yùn)行 db2batch 時(shí)使用的腳本 test_inline_length.sql。 上一頁(yè)45678910111213下一頁(yè) 清單 4. 不同 inline length 設(shè)置的效果$ 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
---------------------------------------------
上一頁(yè)567891011121314下一頁(yè) 從結(jié)果中可以看出,對(duì)于重要操作,較大的 inline length 可以增加 40% 的速度,對(duì)樣本數(shù)據(jù)的查詢也快了 7%。這兩種差異的底層原因是,當(dāng)使用較小的 inline length 時(shí),有超過(guò) 20000 個(gè)幾何圖形(大約 20% 的數(shù)據(jù))以大對(duì)象化的方式存儲(chǔ)。DB2 直接從磁盤讀(寫) LOB 數(shù)據(jù)。而在第二種場(chǎng)景中,大部分的直接讀是不需要的,因?yàn)榭梢杂么鎯?chǔ)在緩沖池中的內(nèi)聯(lián)數(shù)據(jù)來(lái)滿足查詢。注重,大對(duì)象化的數(shù)據(jù)所占的 20% 的比例實(shí)際上不算很壞。假如由于稍微復(fù)雜一點(diǎn)兒的幾何圖形導(dǎo)致更多的數(shù)據(jù)不能以內(nèi)聯(lián)方式存儲(chǔ),那么這里演示的差異還要大大增加。 聚集空間數(shù)據(jù) 根據(jù)某個(gè)屬性聚集數(shù)據(jù)是一種常見(jiàn)的、也是非常有用的技術(shù),這種技術(shù)可以物理地組織一個(gè)表的數(shù)據(jù)。通過(guò)對(duì)底層的觀察可以發(fā)現(xiàn),具有相似值的數(shù)據(jù)經(jīng)常一起被訪問(wèn)。所以,可以將類似的數(shù)據(jù)存儲(chǔ)在接近的位置,使得對(duì)那些數(shù)據(jù)的訪問(wèn)不必分散到表空間中很多不同的頁(yè)上,而是分布在臨近的幾個(gè)頁(yè)上。根據(jù)空間數(shù)據(jù)的空間屬性或幾何圖形間的距離聚集空間數(shù)據(jù)是很自然的。空間查詢是展示局部數(shù)據(jù)訪問(wèn)(換句話說(shuō),現(xiàn)實(shí)中臨近的幾何圖形經(jīng)常被一起訪問(wèn))的最好例子之一。例如,假如您看一個(gè)城市的街道地圖,那么很可能對(duì)那個(gè)城市的所有街道感愛(ài)好,而對(duì)地區(qū)另一邊某個(gè)其他城市的街道不感愛(ài)好。所以在物理上將那個(gè)城市的一些行存儲(chǔ)在相鄰的位置的確很有意義。 在 DB2 中建立數(shù)據(jù)聚集屬性的方法是根據(jù)一個(gè)索引對(duì)表進(jìn)行重組。然而,假如由于空間索引的復(fù)雜性質(zhì)導(dǎo)致 DB2 REORG TABLE 命令不理解空間索引,事情就不會(huì)那么輕易了。關(guān)于這個(gè)問(wèn)題有一個(gè)輕易的方法,即使用一個(gè)列,這個(gè)列的值是根據(jù)涉及的圖形計(jì)算的。這個(gè)列上聲明的數(shù)據(jù)類型必須保證 DB2 能在這個(gè)列上創(chuàng)建一個(gè)本地 B- 樹索引。這里使用空間填充曲線來(lái)保存空間和拓?fù)鋵傩裕ㄕ?qǐng)參閱 參考資料 一節(jié),找到 H. Sagan 撰寫的書籍)。我們?cè)趲缀螆D形上取一個(gè)點(diǎn),即形心點(diǎn), 計(jì)算那個(gè)點(diǎn)在空間填充曲線上的值,并將結(jié)果存儲(chǔ)在一個(gè)附加的列中。最后,在附加列上創(chuàng)建一個(gè)索引,并根據(jù)那個(gè)索引對(duì)表進(jìn)行重組。 上一頁(yè)6789101112131415下一頁(yè) 新聞熱點(diǎn)
疑難解答
圖片精選