【问题标题】:insert into varchar2 column select from xmltype column: extremely slow插入 varchar2 列从 xmltype 列中选择:非常慢
【发布时间】:2014-12-13 04:44:52
【问题描述】:

我正在使用 oracle10gR2 10.2.0.4 和 solaris10 64bit

我需要从 xmltype 列表 (word.testmeta) 中的 xml 中选择数据值 并插入另一个表(word.testwordyy)

desc word.testmeta;
 Name                 Null?    Type
 --------------------------------------
 FILENAME             CHAR(2000)
 XMLDATA              XMLTYPE

desc word.testwordyy;
 Name                 Null?    Type
 ---------------------------------------
 ID                   VARCHAR2(255)
 KEYWORD              VARCHAR2(4000)

我使用 xmltable 并执行:

insert /*+append */ into word.testwordyy(KEYWORD)
select /*+ gather_plan_statistics */ dbms_lob.substr(xmltype.getclobval(b.KEWOR),254)
from word.testmeta , xmltable
(
'$B/mets/KEWOR'
passing
word.testmeta.XMLDATA as B
columns
KEWOR xmltype path '/KEWOR/text()'
)
b

这里是解释计划select * from table(dbms_xplan.display_cursor(null,null,'iostats last'));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
SQL_ID  37ua3npnxx8su, child number 0
-------------------------------------
insert /*+append */ into word.testwordyy(KEYWORD) select /*+ gather_plan_statistics */
dbms_lob.substr(xmltype.getclobval(b.KEWOR),254) from word.testmeta , xmltable ( '$B/mets/KEWOR' passing
    > word.testmeta.XMLDATA as
B columns KEWOR xmltype path '/KEWOR/text()' ) b

Plan hash value: 875848213
-----------------------------------------------------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                   | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  | Writes |
-----------------------------------------------------------------------------------------------------------------------------------
|   1 |  LOAD AS SELECT                     |                        |      1 |        |      1 |00:10:32.72 |   16832 |      7 |   90 |
|   2 |   NESTED LOOPS                      |                        |      1 |     29M|  34688 |00:00:25.95 |   12639 |      5 |    0 |
|   3 |    TABLE ACCESS FULL                | TESTMETA               |      1 |   3638 |   3999 |00:00:00.08 |     909 |      0 |    0 |
|   4 |    COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE |   3999 |        |  34688 |00:00:24.50 |   11730 |      5 |    0 |

Note
-----
   - dynamic sampling used for this statement


21 rows selected.

表word.testmeta中的行数越多,每行花费的时间越多

我的 XML 既简单又小,但需要处理大量(5000000) 当行数超过 8000 时,处理速度非常慢,需要几个小时。 有什么优化或者更快的方法吗?

【问题讨论】:

  • 为什么from中有word.testmeta
  • 单词模式中的testmeta,所以word.testmeta

标签: oracle performance xmltype xmltable


【解决方案1】:

您已将 KEYWOR 列定义为 XMLTYPE。这是为什么? XMLTABLE 的全部意义在于将 XML 结构转换为关系列。如果将列定义为简单的字符串,则可以避免很多不必要的转换。

"标签的内容超过4000个字符>>> 有没有办法在xmltable中对标签的内容进行子串化"

有 XPath substring 函数。

insert /*+append */ into word.testwordyy(KEYWORD)
select /*+ gather_plan_statistics */ b.KEWOR
from word.testmeta 
    , xmltable
      (
        '$B/mets/KEWOR'
        passing
        word.testmeta.XMLDATA as B
        columns
        KEWOR varchar2(4000) path 'substring(KEWOR, 254, 4000)'
      ) b

在这里,我已经开始使用您在原始帖子中使用的偏移量 254 的子字符串。我还明确将其长度设置为 4000。

我认为您在声明列时不需要显式引用text() 节点。

【讨论】:

  • 标签的内容超过4000个字符,所以将KEYWOR列定义为XMLTYPE可以避免错误:ORA-01706: user function result value was too large。是否有任何方法可以像这样在 xmltable 中对 标记的内容进行子串化:KEWOR varchar2(4000) path '/KEWOR/text().substr(4000)'
  • 我得到了 LPX-00601: Invalid token in: '/*/substring(KEWOR, 254, 4000)' with KEWOR varchar2(4000) path 'substring(KEWOR, 254, 4000)'跨度>
  • KEWOR varchar2(4000) path 'substring(KEWOR, 254, 4000)' 不适用于 10gR2 10.2.0.4 版本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多