Database 特定列占用的空间';s数据以及对删除该列的影响

Database 特定列占用的空间';s数据以及对删除该列的影响,database,oracle,oracle12c,Database,Oracle,Oracle12c,我在我的项目中使用Oracle 12c数据库,我有一列“Name”,类型为“VARCHAR2(128 CHAR)NOT NULL”。我的表中大约有25328687行 现在我不需要“Name”列,所以我想删除它。当我计算该列中所有行的数据总大小(使用lengthb和vsize)时,它大约是1.07 GB 由于指定了此列中数据的最大大小,因此并非所有行都将为此列分配128字节(为简单起见,忽略unicode),并且此列消耗的总空间应为128*行数=3242071936字节或3.24 GB Oracl

我在我的项目中使用Oracle 12c数据库,我有一列“Name”,类型为
“VARCHAR2(128 CHAR)NOT NULL”
。我的表中大约有25328687行

现在我不需要“Name”列,所以我想删除它。当我计算该列中所有行的数据总大小(使用lengthb和vsize)时,它大约是1.07 GB


由于指定了此列中数据的最大大小,因此并非所有行都将为此列分配128字节(为简单起见,忽略unicode),并且此列消耗的总空间应为128*行数=3242071936字节或3.24 GB

Oracle为varchar2执行动态分配


因此,如果设置了一个字节字符集,则一个4字符的字符串将占用5个字节,一个长度为1个字节,4个字符占用4个字节。

Oracle Varchar2动态分配内存(定义为可变长度字符串数据类型) Char数据类型是固定长度的字符串数据类型

create table x (a char(5), b varchar2(5));
insert into x value ('RAM', 'RAM');
insert into x value ('RAMA', 'RAMA');
insert into x value ('RAMAN', 'RAMAN');

SELECT * FROM X WHERE length(a) = 3; -> this will return 0 record
SELECT * FROM X WHERE length(b) = 3; -> this will return 1 record (RAM)

SELECT length(a) len_a, length(b) len_b from x ; 
o/p will be like below
len_a | len_b
-------------
5     | 3
5     | 4
5     | 5

正如其他答案所说,
VARCHAR2
列使用的存储是VARying。要获得实际金额的估计值,可以使用

1) 数据字典

SELECT column_name, avg_col_len, last_analyzed
  FROM ALL_TAB_COL_STATISTICS
 WHERE owner        = 'MY_SCHEMA'
   AND table_name   = 'MY_TABLE'
   AND column_name  = 'MY_COLUMN';   
结果
avg\u col\u len
是平均列长度。将它乘以行数25328687,就可以得到该列使用的大致字节数。(如果上次分析的
last\u
为空或与上次大数据更改相比非常旧,则必须首先使用
DBMS\u stats.GATHER\u TABLE\u stats('MY\u SCHEMA','MY\u TABLE')刷新优化器统计数据。

2) 把自己算在样本中

SELECT sum(s), count(*), avg(s), stddev(s)
  FROM (
        SELECT vsize(my_column) as s 
          FROM my_schema.my_table SAMPLE (0.1)
       );
这将计算表中0.1%样本的存储大小

3) 为了确定这一点,我将使用数据的一个子集进行测试

CREATE TABLE my_test TABLESPACE my_scratch_tablespace NOLOGGING AS 
  SELECT * FROM my_schema.my_table SAMPLE (0.1);

-- get the size of the test table in megabytes
SELECT round(bytes/1024/1024) as mb 
  FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';

-- now drop the column
ALTER TABLE my_test DROP (my_column);

-- and measure again
SELECT round(bytes/1024/1024) as mb 
  FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';

-- check how much space will be freed up
ALTER TABLE my_test MOVE;

SELECT round(bytes/1024/1024) as mb 
  FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';
您可以通过在测试表上使用相同的
PCTFREE
COMPRESSION
级别来改进测试