![]() |
Существует несколько типов LOB объектов: BLOB (двоичный большой объект), CLOB (символьный большой объект), NCLOB (национальный символьный большой объект) и BFILE (внешний двоичный файл). LOB объекты делятся на внутренние и внешние.
Внутренние большие объекты Internal LOB – хранятся в базах данных (БД), к ним относятся BLOB, CLOB и NCLOB. Внутренние большие объекты могут быть постоянными или временными:
Внешние большие объекты External LOB – вид данных, который хранится в файлах операционной системы, вне базы данных, а в базе данных на них хранятся ссылки (локаторы). Внешние LOB используют тип данных – BFILE.
LOB объект состоит из двух частей:
Инструментом работы с LOB выступает пакет DBMS_LOB. Он предоставляет методы манипулирования внутренними и внешними LOBами.
В данной статье рассматриваются только постоянные внутренние LOB объекты.
При создании и заполнении данными таких объектов Oracle как LOB объект, таблица, индекс и др. для каждого объекта создается структура, называемая сегментом. При этом имеется особенность при создании сегментов: для каждой не секционированной таблицы создается только один сегмент, для одного не секционированного индекса создается только один сегмент, для каждой секции секционированной таблицы и для каждой секции индекса создается свой сегмент. Однако для каждого LOB столбца таблицы создается не один, а два сегмента. Один сегмент - это LOB-сегмент для хранения данных и второй – это LOB индексный сегмент. LOB индексный сегмент создается автоматически при создании LOB-сегмента и служит для навигации по LOB-сегменту.
Таким образом, если в таблице было указано N столбцов типа LOB, то получим 2*N LOB-сегментов.
LOB сегменты можно увидеть из представления DBA_LOBS запросом:
Select owner, table_name, column_name, segment_name, index_name, tablespace_name From DBA_LOBS Where Owner=’ИМЯ СХЕМЫ’ and Table_name = ‘ИМЯ ТАБЛИЦЫ’;
Рассмотрим порядок работы с таблицами, имеющими LOB столбцы, на примере таблицы AIS.SERVICEMSGXML, функционирующей в нашей системе. В таблице имеются два LOB столбца: XMLOUT и XMLIN - оба типа CLOB.
Команда создания таблицы имеет вид:
CREATE TABLE AIS.SERVICEMSGXML
( ISN NUMBER,
XMLOUT CLOB,
BMLIN CLOB
)
TABLESPACE ADATA
LOB (XMLOUT) STORE AS
( TABLESPACE LOBTBS
ENABLE STORAGE IN ROW
CHUNK 16384)
LOB (XMLIN) STORE AS
( TABLESPACE LOBTBS2
ENABLE STORAGE IN ROW
CHUNK 8192 );
LOB сегменты этой таблицы можно увидеть из представления DBA_LOBS указанным выше запросом:
Select * From DBA_LOBS Where owner=’AIS’ and table_name = ‘SERVICEMSGXML’;
В результате получаем:
OWNER TABLE_NAME COLUMN_NAME SEGMENT_NAME INDEX_NAME TABLESPACE_NAME AIS SERVICEMSGXML XMLOUT SYS_LOB0001677384C00014$$ SYS_IL0001677384C00014$$ LOBTBS AIS SERVICEMSGXML XMLIN SYS_LOB0001677384C00015$$ SYS_IL0001677384C00015$$ LOBTBS2
Мы видим, что в именах сегментов имеются символы SYS_LOB для LOB-сегментов и SYS_IL для индексных сегментов.
Используя представление Oracle DBA_SEGMENTS (при наличии данных в LOB), можно получить размер в байтах, занимаемых LOB-сегментами и LOB-индексными сегментами. Например, для LOB столбца XMLOUT число байтов, занимаемых сегментом, определяется запросом, указанным ниже. При этом в запросе в поле segment_name подставляется имя сегмента, полученного из представления DBA_LOBS.
Select owner, segment_name, bytes, tablespace_name From DBA_SEGMENTS Where segment_name = ‘SYS_LOB0001677384C00014$$';
В результате работы запроса получаем:
OWNER SEGMENT_NAME BYTES TABLESPACE_NAME AIS SYS_LOB0001677384C00014$$ 6969884672 LOBTBS
Для работы с LOB удобным является запрос, в котором используются оба указанных выше представления: DBA_SEGMENTS и DBA_LOBS. Данный запрос покажет (при наличии данных в LOB) не только LOB сегменты всей таблицы и ее индексов, но и размеры в байтах, которые они занимают.
Select s.owner, d.table_name, d.column_name, s.segment_name, s.segment_type, s. bytes, s.tablespace_name From DBA_SEGMENTS s, DBA_LOBS d Where s.segment_name in (d.segment_name,d.index_name) and s.owner=d.owner and d.owner='AIS' and d.table_name = 'SERVICEMSGXML' order by 3;
OWNER TABLE_NAME COLUMN_NAME SEGMENT_NAME SEGMENT_TYPE BYTES AIS SERVICEMSGXML XMLIN SYS_IL0001677384C00015$$ LOBINDEX 65536 AIS SERVICEMSGXML XMLIN SYS_LOB0001677384C00015$$ LOBSEGMENT 131072 AIS SERVICEMSGXML XMLOUT SYS_LOB0001677384C00014$$ LOBSEGMENT 6969884672 AIS SERVICEMSGXML XMLOUT SYS_IL0001677384C00014$$ LOBINDEX 6291456
Иногда важно посмотреть объем, занимаемый самой таблицей без LOB объектов. Это можно увидеть (при наличии данных в таблице) запросом:
Select s.owner, s.segment_name, s.segment_type, s.bytes, s.tablespace_name From DBA_SEGMENTS s Where owner='AIS' and segment_name = 'SERVICEMSGXML';
OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME BYTES AIS SERVICEMSGXML TABLE ADATA 8388608
Как видно, сама таблица составляет порядка 8 MB, в то время как один из LOB занимает 6900 MB. В силу чего таблица была размещена в табличном пространство ADATA среднего размера, в то время как LOB большого объема был размещен в другом существенно большем табличном пространстве LOBTBS. О табличных пространствах LOB изложено ниже.
По умолчанию LOB-сегмент со своим LOB индексным сегментом создается в том же табличном пространстве, что и таблица, в которой находятся LOB столбец. При этом весьма важный момент: LOB-сегмент и LOB-индекс всегда находятся в одном и том же табличном пространстве.
Однако порой целесообразно помещать LOB сегмент в табличное пространство, отличное от пространства таблицы. При этом сами LOB столбцы так же могут размещаться в различных табличных пространствах.
Для размещения LOB в другое табличное пространство, отличное от пространства таблицы, используется структура STORE (начиная с Oracle 11g можно использовать структуру STORE AS SECUREFILE) в команде CREATE таблицы. При этом фразу STORE можно указать только при создании таблицы, т.е. STORE нельзя вставить в процессе модификации таблицы.
Замечание. При создании таблицы по команде Create table с LOB столбцами в ней автоматически для каждого LOB столбца таблицы создается структура STORE. Например, для столбца XMLOUT типа LOB по умолчанию создалась бы структура STORE вида:
LOB (XMLOUT) STORE AS ( TABLESPACE ADATA ENABLE STORAGE IN ROW CHUNK 8192 RETENTION NOCACHE LOGGING).
В ней по умолчанию табличным пространство LOB-а становиться табличное пространство таблицы ADATA и автоматически создаются несколько параметров.
Если есть необходимость управлять табличным пространством или параметрами STORE, надо явно описать конструкцию STORE при создании таблицы (что и было сделано при создании таблицы AIS.SERVICEMSGXML по каждому LOB столбцу). При этом, если используется конструкция STORE AS SECUREFILE, то ее необходимо явно прописывать в команде Create table.
Основными атрибутами конструкции STORE являются:
SELECT DBMS_LOB.GETLENGTH(XMLIN) FROM AIS.SERVICEMSGXML ORDER BY 1 DESC;
SELECT ROUND(SUM(S1)/SUM(S2),3)*100 FROM ( SELECT COUNT(*) s1, 0 s2 FROM AIS.SERVICEMSGXML WHERE DBMS_LOB.GETLENGTH(XMLIN)<=4000 UNION ALL SELECT 0,COUNT(*) s2 FROM AIS.SERVICEMSGXML) ;
select DBMS_LOB.GETLENGTH(XMLOUT) bytes, count(1) distincts from AIS.SERVICEMSGXML m group by DBMS_LOB.GETLENGTH(XMLOUT) order by 2 desc;
В Oracle 11g структура STORE получила дальнейшее развитие, так появилась возможность сжимать данные LOB-ов и исключить их дублирование. Для этого вместо конструкции STORE пишется конструкция STORE AS SECUREFILE. В ней дополнительно к существующим атрибутам добавились новые атрибуты, среди них:
SELECT SUM(DBMS_LOB.GETLENGTH(XMLIN)) FROM AIS.SERVICEMSGXML T WHERE T.UPDATED >SYSDATE-1/24;
ALTER TABLE AIS.SERVICEMSGXML MODIFY LOB(XMLIN) (NOCOMPRESS);
ALTER TABLE AIS.SERVICEMSGXML MODIFY LOB(XMLIN) (COMPRESS HIGH);
Вывод. При создании STORE cледует оценить, что эффективнее: хранить LOB в таблице или вынести их из таблицы (режим ENABLE или DISABLE), обосновать целесообразность кэширования LOB и определить более эффективный размер CHUNK.
Ряд атрибутов STORE могут быть добавлены или модифицированы в любой момент после создания таблицы командой ALTER TABLE (не модифицируются такие атрибуты как CHUNK и ENABLE/DISABLE STORAGE IN ROW).
Например, для столбца XMLIN таблицы SERVICEMSGXML модификация атрибутов NOCACHE на CACHE осуществляется так же по команде ALTER
ALTER TABLE AIS.SERVICEMSGXML MODIFY LOB (XMLIN) (CACHE);
Для режима STORE AS SECUREFILE можно модифицировать или добавлять новые атрибуты. Например, добавить DEDUPLICATE и модифицировать COMPRESS с LOW на HIGH по команде:
ALTER TABLE AIS.SERVICEMSGXML MODIFY LOB (XMLIN) (DEDUPLICATE); ALTER TABLE AIS.SERVICEMSGXML MODIFY LOB(XMLIN) (COMPRESS HIGH);
В отличие от обычных таблиц удаление данных из таблицы с LOB не освобождает табличное пространство, занимаемое LOB. Для освобождения табличного пространства используется команда SHRINK либо TRUNCATE таблицы или (что более эффективно) TRUNCATE секции для секционированных таблиц.
Сжатие пространства для не секционированной таблицы осуществляется по команде
ALTER TABLE SERVICEMSGXML MODIFY LOB (XMLIN) (SHRINK SPACE CASCADE);
Для секционированной таблицы команды с shrink и truncate имеют вид:
ALTER TABLE имя таблицы MODIFY PARTITION имя партиции LOB (имя LOB столбца) (SHRINK SPACE); ALTER TABLE имя таблицы TRUNCATE PARTITION имя партиции UPDATE GLOBAL INDEXES;
Фраза UPDATE GLOBAL INDEXES в TRUNCATE обеспечивает исправность глобальных индексов после очистки секции по Truncate.