Насколько велик XML-тип Oracle при хранении в виде BINARY XML
Документация 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?
Пожалуйста, помогите, размер стола составляет 340 ГБ, поэтому стоит рассмотреть варианты хранения...
Ответы
Ответ 1
Формат двоичного формата Oracle соответствует "Compact XML Schema Aware XML Format", сокращенно CSX. Закодированные данные сохраняются как поле BLOB. Подробная информация о бинарном формате XML доступна в документации Oracle (здесь и здесь).
Реальный размер поля данных зависит от параметров хранения больших объектов в столбце XMLType. Например. если включена опция storage in row
, тогда небольшие документы, хранящиеся непосредственно с другими данными, и vsize()
возвращают соответствующие значения.
В действительности Oracle создает базовый столбец BLOB с именем системы, который можно найти, запросив 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'
)
Этот запрос возвращает имя скрытого столбца системы, которое выглядит как SYS_NC00002$
.
После этого можно получить размер полей с регулярным вызовом dbms_lob.getlength()
против скрытого столбца:
select dbms_lob.getlength(SYS_NC00002$) from t
Ответ 2
Фактическое потребление памяти сохраняется в представлении, называемом user_segments. Чтобы найти коррелирующий LOB в столбце, вам придется присоединиться к user_segments с 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
Ответ 3
[rep issue, не разрешено оставлять комментарии]
вы хотели сказать "между вопросами", как я понял. единственное сходство - проблема с памятью, подумал, что это может быть полезно для оценки "догадки". вы не указали, какой тип данных вы собираетесь хранить как bXML.
распаковывает двоичный XML-текст в текст
Если чистый XML, то это зависит от того, какой компрессор вы собираетесь использовать. Обычно lzma | gzip используется для двоичного сжатия. Возможно, я пишу о слишком очевидных вещах, но все, что я знаю