将Oracle XMLType存储为BINARY XML时有多大

时间:2014-07-15 17:41:10

标签: sql xml oracle oracle11gr2

Oracle文档声称它将XMLType存储为BINARY XML而不是CLOB。但是如何找出二进制xml占用了多少空间?

CREATE TABLE t (x XMLTYPE) XMLTYPE x STORE AS BINARY XML;

SELECT vsize(x), dbms_lob.getlength(XMLTYPE.getclobval(x)) FROM t;

94 135254
94  63848
94  60188

因此,vsize似乎是某种指针或LOB定位器的大小,getclobval将二进制XML解包为文本。但是二进制XML本身的存储大小呢?

请帮助,表格大小为340GB,因此值得研究存储选项......

3 个答案:

答案 0 :(得分:12)

Oracle二进制XML格式对应于" Compact Schema Aware XML Format"缩写为CSX。编码数据存储为BLOB字段。有关Oracle文档(herehere)中提供的二进制XML格式的详细信息。

数据字段的实际大小取决于XMLType列的LOB存储参数。例如。如果启用了storage in row选项,那么直接与其他数据一起存储的小文档和vsize()将返回适当的值。

实际上,Oracle使用系统名称创建底层BLOB列,可以通过查询user_tab_cols视图找到:

select table_name, column_name, data_type 
from user_tab_cols 
where 
  table_name = 'T' and hidden_column = 'YES'
  and
  column_id = (
      select column_id 
      from user_tab_cols 
      where table_name = 'T' and column_name = 'X'
  ) 

此查询返回系统隐藏的列名,其类似于SYS_NC00002$

之后,可以通过定期dbms_lob.getlength()调用隐藏列来获取字段大小:

select dbms_lob.getlength(SYS_NC00002$) from t

答案 1 :(得分:1)

实际存储消耗存储在名为user_segments的视图中。要查找与列相关的LOB,您必须使用user_lobs加入user_segments:

CREATE TABLE clob_table (x XMLTYPE) XMLTYPE x store as CLOB;

CREATE TABLE binaryxml_table (x XMLTYPE) XMLTYPE x STORE AS BINARY XML;

INSERT INTO clob_table (x) SELECT
  XMLELEMENT("DatabaseObjects",
    XMLAGG(
      XMLELEMENT("Object", XMLATTRIBUTES(owner, object_type as type, created, status), object_name)
    )
  ) as x
FROM all_objects;

INSERT INTO binaryxml_table (x) select
  XMLELEMENT("DatabaseObjects",
    XMLAGG(
      XMLELEMENT("Object", XMLATTRIBUTES(owner, object_type as type, created, status), object_name)
    )
  ) as x
FROM all_objects;

SELECT lobs.table_name,
  (SELECT column_name
     FROM user_tab_cols
       WHERE table_name = lobs.table_name AND data_type = 'XMLTYPE'  AND column_id =
         (SELECT column_id
            FROM user_tab_cols
              WHERE table_name = lobs.table_name AND column_name = lobs.column_name
          )
    ) column_name,
  seg.segment_name, seg.bytes
    FROM user_lobs lobs, user_segments seg
      WHERE lobs.segment_name = seg.segment_name;

TABLE_NAME      COLUMN_NAME SEGMENT_NAME                 BYTES
--------------- ----------- ------------------------- --------
BINARYXML_TABLE X           SYS_LOB0000094730C00002$$  7536640 
CLOB_TABLE      X           SYS_LOB0000094727C00002$$ 19922944 

答案 2 :(得分:-1)

[rep问题,不允许发表评论] 你想说"问题"据我所知。唯一的相似之处是存储空间问题,认为它可能有助于"猜测"估计。你没有提到你要存储为bXML的数据类型。

  

将二进制XML解包为文本

如果是纯XML,那么它取决于您将要使用的压缩器。通常lzma | gzip用于二进制压缩。也许我正在写关于太明显的事情,但这就是我所知道的