Oracle хранит много информации о пространстве, которое используется для таблиц, индексов и прочего. Все те вещи, которые занимают пространство, живут в сегменте , который можно найти в представлении словаря данных USER_SEGMENTS
:
CREATE TABLE t (i NUMBER, r LONG RAW);
INSERT INTO t (i) VALUES (1);
SELECT segment_type, bytes, blocks FROM user_segments WHERE segment_name='T';
SEGMENT_TYPE BYTES BLOCKS
TABLE 65536 8
Итак, почти пустая таблица занимает 8 блоков по 8 КБ, которые вместе занимают 64 килобайта. Если вы вставите некоторые LONG RAW
тестовые данные, размер увеличится соответственно:
INSERT INTO t
SELECT object_id, hextoraw(lpad('AA',1000,'AA'))
FROM all_objects
WHERE ROWNUM <= 10000;
SELECT segment_type, bytes, blocks FROM user_segments WHERE segment_name='T';
SEGMENT_TYPE BYTES BLOCKS
TABLE 6291456 768
Наиболее точным измерением будет создание тестовой таблицы с выбранным условием и ее измерение:
CREATE TABLE testtable NOLOGGING TABLESPACE my_scratch_ts AS
SELECT * FROM my_table WHERE my_column = ...;
Если длина LONG RAW
s распределена равномерно, вы можете использовать процентный подход, который вы упомянули.
Тип данных LONG
и LONG RAW
- настоящая боль в работе, поэтому Oracle рекомендует не использовать его для новых проектов. Вам необходимо выполнить запросы в PL / SQL, чтобы определить фактический размер:
DECLARE
s NUMBER := 0;
BEGIN
FOR c IN (SELECT r, -- get the long raw column to measure it's length
vsize(i) as v -- get the size of the other column(s)
FROM t
WHERE i between 1700 and 1800) -- example for your selection
LOOP
s := s + c.v; -- add the lengths other columns
s := s + utl_raw.length(c.r); -- add the length of the long raw
END LOOP;
dbms_output.put_line('total size of selection = '||s||' bytes');
END;
/
Когда вы включаете DBMS_OUTPUT
в SQL Developer, он говорит что-то вроде:
total size = 24000 bytes