Oracle 11.更新BLOB字段。 DB文件顺序读取不当慢?

我有一个表和Oracle(11企业)架构

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); 

和第三方库(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行。 在同一时间我有其他表与blob(CLOB更具体),包含600 + k行相同的更新工作正确的同一架构。

在Oracle中,LOB(包括BLOB)存储为:

  • 在表中的LOB – 如果LOB小于3900字节,它可以存储在表行内; 默认情况下这是启用的,除非你指定DISABLE STORAGE IN ROW
  • 正常的LOB – 存储在一个单独的段,在表外,你甚至可以把它放在另一个表空间; 对于这些:
    • 最less的CHUNK字节被分配并完全重新logging(即使LOB只有1个字节)
    • 在LOB列后面有一个内部中间索引,它在更新上有争议,并可能实际上对它们进行序列化
    • 访问是多层次的,因此相对较慢
    • 与NOCACHE选项,服务员是“直接path读取” – 默认
    • 用CACHE选项,服务员是“db file sequential read”
      • 不考虑CACHE_SIZE_THRESHOLD,所以大的LOB会浪费你的caching

因此,如果您的LOB大于4 kB,则它们会变得相对较慢, 这可能只是您的情况。 我会检查大小。

我将检查USER_LOBS(或DBA_LOBS),以查看“好”和“慢”LOB列在其定义中的差异。

Metalink注释ID 66431.1对此进行了描述,如果您有权访问,可能会对您感兴趣。

更新 :看起来难以解释的“db文件顺序读取”狂野的数量迷住了我,我做了一些search,发现奇怪的事情可能会发生大规模删除后的指标索引 。 只是一个猜测,但看起来非常相似你的情况。 如果是这样,我会完全重buildlob列 。 (移动一个lob列也可能重buildlob索引 – 我不确定)。