Performance

Oracle 11. 更新 BLOB 欄位。Db 文件順序讀取不恰當地慢?

  • January 27, 2012

我已經和 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 索引 - 我不確定)。

引用自:https://serverfault.com/questions/345253