Oracle 23c부터 Inline LOB의 최대 크기를 8000 바이트로 설정할 수 있습니다.
LOB values are stored either in the table row (inline) or outside of the table row (out-of-line). The maximum size of the inline LOB is increased to 8000 bytes, allowing larger LOB values being stored inside a row. Earlier, the maximum size was 4000. This provides better input-output performance while processing LOB columns. You can experience the improved performance while running operations, such as full table scans, range scans, and DML.
참고로 LOB 타입은 사용자가 설정한 데이터베이스 캐릭터 셋과 무관하게 한 문자가 2 바이트로 저장되는 AL16UTF16 캐릭터 셋을 사용합니다. 관련 내용은 Storing Documents in Multiple Languages in LOB Data Types에서 확인할 수 있습니다.
Data in CLOB columns is stored in the AL16UTF16 character set when the database character set is multibyte, such as UTF8 or AL32UTF8. This means that the storage space required for an English document doubles when the data is converted. Storage for an Asian language document in a CLOB column requires less storage space than the same document in a LONG column using AL32UTF8, typically around 30% less, depending on the contents of the document.
테스트를 위해 t1 테이블의 c1, c2 칼럼에 대한 Inline LOB의 최대 크기를 8000 바이트로 설정하겠습니다. ENABLE STORAGE IN ROW 절에 Inline LOB의 최대 크기를 지정할 수 있습니다.
-- 1
DROP TABLE t1 PURGE;
CREATE TABLE t1 (c1, c2)
LOB (c1) STORE AS SECUREFILE (ENABLE STORAGE IN ROW 8000)
LOB (c2) STORE AS SECUREFILE (ENABLE STORAGE IN ROW 8000)
AS
SELECT TO_CLOB (LPAD ('X', 3984, 'X')) -- (3984 * 2) + 32 = 8000
, TO_CLOB (LPAD ('X', 3985, 'X')) -- (3985 * 2) + 32 = 8002
FROM XMLTABLE ('1 to 10000');
아래 쿼리로 8000 바이트의 값을 입력한 c1 칼럼은 Inline LOB, 8002 바이트의 값을 입력한 c2 칼럼은 Out-of-line LOB에 값이 저장된 것을 확인할 수 있습니다. 참고로 SecureFile LOB은 32 바이트의 오버헤드를 가집니다.
-- 2-1
SELECT bytes / POWER (1024, 2) AS mb
FROM user_segments
WHERE segment_name = 'T1';
MB
--
96
1개의 행이 선택되었습니다.
-- 2-2
SELECT a.column_name, b.bytes / POWER (1024, 2) AS mb
FROM user_lobs a
, user_segments b
WHERE a.table_name = 'T1'
AND b.segment_name = a.segment_name;
COLUMN_NAME MB
----------- -----
C1 0.25
C2 80.31
2 행이 선택되었습니다.
Inline LOB의 최대 크기의 기본값은 기존과 동일한 4000 바이트입니다. 테스트를 위해 아래와 같이 t2 테이블을 생성하겠습니다.
-- 3
DROP TABLE t2 PURGE;
CREATE TABLE t2 (c1, c2)
AS
SELECT TO_CLOB (LPAD ('X', 1984, 'X')) -- (1984 * 2) + 32 = 4000
, TO_CLOB (LPAD ('X', 1985, 'X')) -- (1985 * 2) + 32 = 4002
FROM XMLTABLE ('1 to 10000');
아래 쿼리로 4000 바이트의 값을 입력한 c1 칼럼은 Inline LOB, 4002 바이트의 값을 입력한 c2 칼럼은 Out-of-line LOB에 값이 저장된 것을 확인할 수 있습니다.
-- 4-1
SELECT bytes / POWER (1024, 2) AS mb
FROM user_segments
WHERE segment_name = 'T2';
MB
--
80
1개의 행이 선택되었습니다.
-- 4-2
SELECT a.column_name, b.bytes / POWER (1024, 2) AS mb
FROM user_lobs a
, user_segments b
WHERE a.table_name = 'T2'
AND b.segment_name = a.segment_name;
COLUMN_NAME MB
----------- -----
C1 0.25
C2 80.31
2 행이 선택되었습니다.
아래 쿼리로 Inline LOB의 최대 크기를 조회할 수 있습니다.
-- 5-1
SELECT table_name, column_name, data_type, data_length
FROM user_tab_columns
WHERE table_name IN ('T1', 'T2');
TABLE_NAME COLUMN_NAME DATA_TYPE DATA_LENGTH
---------- ----------- --------- -----------
T1 C1 CLOB 8200
T1 C2 CLOB 8200
T2 C1 CLOB 4000
T2 C2 CLOB 4000
4 행이 선택되었습니다.
-- 5-2
SELECT table_name, column_name, max_inline
FROM user_lobs
WHERE table_name IN ('T1', 'T2');
TABLE_NAME COLUMN_NAME MAX_INLINE
---------- ----------- ----------
T1 C1 8000
T1 C2 8000
T2 C1 4000
T2 C2 4000
4 행이 선택되었습니다.