Oracle 11. 更新 BLOB 欄位。Db 文件順序讀取不恰當地慢?
我已經和 Oracle (11 Enterprise) 架構和一個表
CREATE TABLE USER.WSP_BUNDLE ( NODE_ID RAW(16) NOT NULL, BUNDLE_DATA BLOB NOT NULL ); CREATE UNIQUE INDEX USER.WSP_BUNDLE_IDX ON USER.WSP_BUNDLE(NODE_ID);
和操縱它的第 3 方庫(Java 6、JDBC - 最新的 jdbc 驅動程序)。
Oracle 分析器 (tkprof) 顯示lib 執行此類語句的總時間大約有 50%:
update WSP_BUNDLE set BUNDLE_DATA = :1 where NODE_ID = :2
TKProf 數據
Plan Hash: 4085453680 update WSP_BUNDLE set BUNDLE_DATA = :1 where NODE_ID = :2 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 264 0.00 0.00 0 0 0 0 Execute 400 30.59 382.88 141451 1623163 3233827 400 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 664 30.59 382.88 141451 1623163 3233827 400 Misses in library cache during parse: 0 Optimizer mode: ALL_ROWS Parsing user id: 87 Rows Row Source Operation ------- --------------------------------------------------- 0 UPDATE WSP_BUNDLE (cr=8753 pr=707 pw=706 time=0 us) 1 INDEX UNIQUE SCAN WSP_BUNDLE_IDX (cr=3 pr=0 pw=0 time=0 us cost=2 size=104 card=1)(object id 75730) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ db file sequential read 141251 5.53 328.04 direct path write 402 0.09 0.43 SQL*Net more data from client 142158 1.04 11.89 direct path read 200 0.03 0.07 Disk file operations I/O 1 0.00 0.00 SQL*Net message to client 400 0.00 0.00 SQL*Net message from client 400 0.29 0.50 log file switch (private strand flush incomplete) 5 0.05 0.23 asynch descriptor resize 139723 7.46 8.57 buffer busy waits 2 0.00 0.00 log file switch (checkpoint incomplete) 3 0.18 0.27 log file sync 2 0.00 0.00
有人可以解釋/提示我發生了什麼事嗎?為什麼更新這麼慢?
表 WSP_BUNDLE 包含大約 200+k 行。同時,我在同一架構中還有其他表,其中包含 600+k 行的 blob(更具體地說是 CLOB),其中類似的更新可以正常工作。
在 Oracle 中,LOB(包括 BLOB)儲存為:
in-the-table LOB - 如果 LOB 小於 3900 字節,則可以將其儲存在表行內;預設情況下,這是啟用的,除非您指定 DISABLE STORAGE IN ROW
普通 LOB - 儲存在表之外的單獨段中,您甚至可以將其放在另一個表空間中;對於這些:
至少分配了 CHUNK 字節並完全重新記錄(即使 LOB 只有 1 個字節)
LOB 列後面有一個內部中間索引,它在更新時會引起爭議,實際上可能會序列化它們
訪問是多級的,因此相對較慢
使用 NOCACHE 選項,服務員是“直接路徑讀取” - 預設
使用 CACHE 選項,服務員是“數據庫文件順序讀取”
- 其中不考慮 CACHE_SIZE_THRESHOLD,因此大 LOB 會浪費您的記憶體
因此,如果您的 LOB 大於 4 kB,它們會變得相對較慢,這可能只是您的情況。我會檢查尺寸。
我將檢查 USER_LOBS(或 DBA_LOBS)以了解“好”和“慢” LOB 列的定義有何不同。
Metalink 註釋 ID 66431.1 對此進行了描述,如果您可以訪問,您可能會對此感興趣。
更新:被看似無法解釋的大量“db 文件順序讀取”迷住了,我做了一些搜尋,發現在大量 DELETEs 之後 lob 索引可能會發生奇怪的事情。只是一個猜測,但看起來與您的情況非常相似。如果是這樣,我將完全重建 lob 列。(移動 lob 列也可能重建 lob 索引 - 我不確定)。