Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How big is an Oracle XMLType when stored as BINARY XML

The Oracle documentation claims that it stores XMLType more compact as BINARY XML than as CLOB. But how do I find out how much space is taken by the binary 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

So, vsize seems to be the size of some sort of pointer or LOB locator, and getclobval unpacks the binary XML into text. But what about the storage size of the binary XML itself?

Please help, the table size is 340GB, so it's worth looking into storage options...

like image 238
wolφi Avatar asked Jul 15 '14 17:07

wolφi


People also ask

What is the size of XMLType in Oracle?

XML Identifier Length Limit – Oracle XML DB supports only XML identifiers that are 4000 characters long or shorter.

What is XMLType datatype?

XMLType datatype can be used as the datatype of columns in tables and views. Variables of XMLType can be used in PL/SQL stored procedures as parameters, return values, and so on. You can also use XMLType in SQL, PL/SQL, and Java (through JDBC).

What abstract datatype does Oracle use to store XML content?

XMLType is an abstract data type, so it is straightforward to create an XMLType table or column. The basic CREATE TABLE statement, specifying no storage options and no XML schema, stores XMLType data as binary XML. Example 3-1 creates an XMLType column, and Example 3-2 creates an XMLType table.

What is Oracle XMLType?

XMLType is a system-defined opaque type for handling XML data. It as predefined member functions on it to extract XML nodes and fragments. You can create columns of XMLType and insert XML documents into it.


2 Answers

Oracle Binary XML format corresponds to "Compact Schema Aware XML Format" abbreviated as CSX. Encoded data stored as BLOB field. Details about binary XML format available from Oracle documentation (here and here).

Real size of data field depends on LOB storage parameters of XMLType column. E.g. if storage in row option enabled then small documents stored directly with other data and vsize() returns appropriate values.

In reality Oracle creates underlying BLOB column with system name, which can be found by querying user_tab_cols view:

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

This query returns system hidden column name which looks like SYS_NC00002$.

After that it's possible to get size of fields with regular dbms_lob.getlength() call against hidden column:

select dbms_lob.getlength(SYS_NC00002$) from t
like image 88
ThinkJet Avatar answered Oct 01 '22 02:10

ThinkJet


Actual storage consumption is stored in a view called user_segments. To find the correlating LOB to the column you will have to join user_segments with user_lobs:

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 
like image 42
gvenzl Avatar answered Oct 01 '22 02:10

gvenzl