About Compress Tables and structure
本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客
昨天朋友问到压缩表的细节问题,我准备用实验来解释,最近很久也没写博客了,就正好完善一下,贴出来。
首先我们来看下10g的表压缩:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
SQL> create table t1 as select * from dba_objects; Table created. SQL> create table t2_nocompress as select * from t1 where 1=2; Table created. SQL> create table t3_compress compress as select * from t1 where 1=2; Table created. SQL> set timing on SQL> insert /*+append */ into t2_nocompress select * from t1 where rownum < 50001; 50000 rows created. Elapsed: 00:00:01.50 SQL> commit; Commit complete. Elapsed: 00:00:00.01 SQL> insert /*+append */ into t3_compress select * from t1 where rownum < 50001; 50000 rows created. Elapsed: 00:00:01.64 SQL> commit; Commit complete. Elapsed: 00:00:00.00 |
可以看到基本上没有差别,实际上压缩表和普通表在insert和delete上,基本上没啥区别(可能与细微差别,压缩表性能适当低一点).
那么update 呢? 其实,主要是体现在update上,为什么呢 ?
1 2 3 4 5 6 7 8 |
SQL> select table_name,PCT_FREE from user_tables where table_name like '%T%COMPRESS%'; TABLE_NAME PCT_FREE ------------------------------ ---------- T_COMPRESS1 10 T_COMPRESS2 0 T2_NOCOMPRESS 10 T3_COMPRESS 0 |
我们可以看到,其实压缩表和普通表一个不同之处在于其pctfree属性的差别。 针对压缩表,其pct属性是0,那么这样就很可能会导致
update时出现行迁移/行链接,这样也就必然会导致操作时代价变得更大,下面我来实验一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------------- ---------- redo size 13364276 SQL> set timing on SQL> update t2_nocompress set object_id=object_id+1; 50000 rows updated. Elapsed: 00:00:07.00 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------------- ---------- redo size 28907280 Elapsed: 00:00:00.02 SQL> commit; Commit complete. Elapsed: 00:00:00.01 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------------- ---------- redo size 28907448 Elapsed: 00:00:00.02 SQL> update t3_compress set object_id=object_id+1; 50000 rows updated. Elapsed: 00:00:31.91 SQL> commit; Commit complete. Elapsed: 00:00:00.02 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------------- ---------- redo size 42239932 Elapsed: 00:00:00.01 SQL> |
可以看到,普遍表update只需要7s,而压缩表update花了32s左右,是其4倍多. 而普通版update产生的redo
size是:15543172 ,压缩表产生的redo size是:13332484 在redo 大小上,差别不大。
在11g中,oracle引入了advanced compress特性,其实是在原来10g的压缩上更进一步了,可以实现OLTP类型压缩。
这么说明下,其实10g版本中的压缩表本身是为DSS类应用设计的,对于OLTP应用并不适用,另外就是其压缩数据的话,
限制比较多,对于普通的dml操作都是无法进行压缩的,只满足如下几种情况:
1. 使用sql*loader direct path加载.
2. 使用create table as select 方式操作.
3. 使用parallel insert操作.
4. 使用append hint.
在11g中,普通的dml操作也是可以压缩的,不管是单行操作,还是bulk 操作,均可压缩. 另外还提供了表空间级别的压缩.
表空间压缩是指,创建表空间时,就创建compress表空间,随后所有创建在该表空间的表都要被自动压缩.
鉴于11g新的特性,那么在11g的文档中,针对以前老的方式定义为basic compression,11g本身的压缩定义为OLTP compression.
另外11.2中,还引入了混合列压缩,不过该特性只能在oracle exadata上使用. 而OLTP compression则适用于OLTP和DSS。
下面我们再来演示下11g的OLTP compression.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
SQL> show user USER is "ROGER" SQL> select * from v$version where rownum < 3; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production PL/SQL Release 11.2.0.3.0 - Production SQL> create table t1(owner varchar2(30),object_id number); Table created. SQL> insert into t1 select owner,object_id from dba_objects where rownum < 50001; 50000 rows created. SQL> commit; Commit complete. SQL> SQL> create table t2_compress_bas(owner varchar2(30),object_id number) compress basic; Table created. SQL> create table t3_compress_oltp(owner varchar2(30),object_id number) compress for oltp; Table created. ---测试insert SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 1748760 redo size for lost write detection 0 redo size for direct writes 608872 Elapsed: 00:00:00.12 SQL> insert /*+append */ into t2_compress_bas select * from t1 where rownum < 50001; 50000 rows created. Elapsed: 00:00:00.10 SQL> commit; Commit complete. Elapsed: 00:00:00.03 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 2361200 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> SQL> SQL> insert into t3_compress_oltp select * from t1 where rownum < 50001; 50000 rows created. Elapsed: 00:00:00.43 SQL> commit; Commit complete. Elapsed: 00:00:00.01 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 4916332 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> 对比情况: basic compression OLTP compression time: 0.1s 0.43 redo size: 1221312 2555132 ---测试update SQL> l 1 select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4* and a.name like 'redo size%' SQL> / NAME VALUE ---------------------------------------------------------------- ---------- redo size 4916332 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.00 SQL> update t2_compress_bas set object_id=object_id+1; 50000 rows updated. Elapsed: 00:00:01.16 SQL> commit; Commit complete. Elapsed: 00:00:00.04 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 17327816 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> / NAME VALUE ---------------------------------------------------------------- ---------- redo size 17327816 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> update t3_compress_oltp set object_id=object_id+1; 50000 rows updated. Elapsed: 00:00:01.07 SQL> commit; Commit complete. Elapsed: 00:00:00.01 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 29768412 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> 对比情况: basic compression OLTP compression time: 1.16 1.07 redo size: 12411484 12440596 --测试delete SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 29768412 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> delete from t2_compress_bas where rownum < 5001; 5000 rows deleted. Elapsed: 00:00:00.18 SQL> commit; Commit complete. Elapsed: 00:00:00.02 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 31035408 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> delete from t3_compress_oltp where rownum < 5001; 5000 rows deleted. Elapsed: 00:00:00.12 SQL> commit; Commit complete. Elapsed: 00:00:00.01 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name like 'redo size%'; NAME VALUE ---------------------------------------------------------------- ---------- redo size 32296752 redo size for lost write detection 0 redo size for direct writes 1217744 Elapsed: 00:00:00.01 SQL> 对比情况: basic compression OLTP compression time: 0.18 0.12 redo size: 1266996 1261344 最后来看下11g中的oltp compression模式跟普通表的update比较: SQL> create table t4 as select * from t3_compress_oltp where 1=1; Table created. Elapsed: 00:00:00.18 SQL> update t4 set object_id=object_id+1; 45000 rows updated. Elapsed: 00:00:01.03 SQL> commit; Commit complete. Elapsed: 00:00:00.00 SQL> update t3_compress_oltp set object_id=object_id+1; 45000 rows updated. Elapsed: 00:00:01.04 SQL> commit; Commit complete. Elapsed: 00:00:00.08 |
可以看到,在11g中,oltp compression似乎比较成熟了,基本上跟普通版相当了。 至于basic compression和oltp compression,
总的来说,差不多。差别主要在update上。
最后我们再来看下10g中压缩表 block的结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
Block header dump: 0x0080035c Object id on Block? Y seg/obj: 0xeafa csc: 0x00.655aba itc: 3 flg: E typ: 1 - DATA brn: 0 bdba: 0x800359 ver: 0x01 opc: 0 inc: 0 exflg: 0 Itl Xid Uba Flag Lck Scn/Fsc 0x01 0xffff.000.00000000 0x00000000.0000.00 C--- 0 scn 0x0000.00655aba 0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000 data_block_dump,data header at 0xd0d987c =============== tsiz: 0x1f80 hsiz: 0x2f4 pbl: 0x0d0d987c bdba: 0x0080035c 76543210 flag=-0------ ntab=2 --表示存了2个table的信息(这里其实表是一个是压缩块的映射关系,另外一个就是实际的行数据) nrow=345 frre=-1 fsbo=0x2f4 fseo=0x2f8 avsp=0x4 tosp=0x4 r0_9ir2=0x0 mec_kdbh9ir2=0x15 --表示不重复记录只有1条,即block内只需要记录一条记录就行了。 76543210 shcf_kdbh9ir2=---------- 76543210 flag_9ir2=--R---OC fcls_9ir2[11]={ 0 32768 32768 32768 32768 32768 32768 32768 32768 32768 7 } -这是一个用于换算的数组 perm_9ir2[13]={ 5 11 0 12 10 8 6 9 7 1 2 4 3 } --这是一个序列配置,表示col5 对应实际数据列的col0,col 11对应col1,以此类推 0x3a:pti[0] nrow=47 offs=0 --表示符号表(映射关系表里面的数据条数) 0x3e:pti[1] nrow=298 offs=47 --表示不重复数据的条数 0x42:pri[0] offs=0x1e88 0x44:pri[1] offs=0x1e6f 0x46:pri[2] offs=0x1e69 。。。。。。。。 0x2f2:pri[344] offs=0x2f8 block_row_dump: tab 0, row 0, @0x1e88 tl: 9 fb: --H-FL-- lb: 0x0 cc: 6 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 bindmp: 00 03 06 ff 2d 2e 2e 2e 29 tab 0, row 1, @0x1e6f tl: 25 fb: --H-FL-- lb: 0x0 cc: 8 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2d col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34 bindmp: 00 03 08 00 2c db 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34 tab 0, row 2, @0x1e69 tl: 6 fb: --H-FL-- lb: 0x0 cc: 10 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2d col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34 col 8: [ 7] 43 4c 55 53 54 45 52 col 9: [ 7] 78 6e 04 0f 0e 0f 2d bindmp: 00 05 0a 01 2b 2c tab 0, row 3, @0x1e63 tl: 6 fb: --H-FL-- lb: 0x0 cc: 10 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2d col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34 col 8: [ 5] 49 4e 44 45 58 col 9: [ 7] 78 6e 04 0f 0e 0f 2d bindmp: 00 23 0a 01 28 2c tab 0, row 4, @0x1e5e ........ ........ .......... tab 0, row 44, @0x1f6a tl: 10 fb: --H-FL-- lb: 0x0 cc: 1 col 0: [ 7] 78 6e 04 0f 0e 0f 2d bindmp: 00 0e cf 78 6e 04 0f 0e 0f 2d tab 0, row 45, @0x1f74 tl: 8 fb: --H-FL-- lb: 0x0 cc: 1 col 0: [ 5] 56 41 4c 49 44 bindmp: 00 04 cd 56 41 4c 49 44 tab 0, row 46, @0x1f7c tl: 4 fb: --H-FL-- lb: 0x0 cc: 1 col 0: [ 1] 4e bindmp: 00 0a c9 4e 前面是tab0 信息,下面是tab1信息。 tab 1, row 0, @0x1dd2 tl: 14 fb: --H-FL-- lb: 0x0 cc: 13 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2d col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34 col 8: [ 7] 43 4c 55 53 54 45 52 col 9: [ 7] 78 6e 04 0f 0e 0f 2d col 10: [ 2] c1 03 col 11: [ 6] 43 5f 4f 42 4a 23 col 12: [ 2] c1 03 bindmp: 2c 00 04 0a 02 2a ce 43 5f 4f 42 4a 23 2a ........... ........... ........... tab 1, row 296, @0x306 tl: 30 fb: --H-FL-- lb: 0x0 cc: 13 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2f col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 36 col 8: [ 5] 49 4e 44 45 58 col 9: [ 7] 78 6e 04 0f 0e 0f 2f col 10: [ 3] c2 04 0b col 11: [16] 49 5f 44 45 46 53 55 42 50 41 52 54 4c 4f 42 24 col 12: [ 3] c2 04 0b bindmp: 2c 00 04 0a 10 cb c2 04 0b d8 49 5f 44 45 46 53 55 42 50 41 52 54 4c 4f 42 24 cb c2 04 0b tab 1, row 297, @0x2f8 tl: 14 fb: --H-FL-- lb: 0x0 cc: 13 col 0: *NULL* col 1: [ 5] 56 41 4c 49 44 col 2: [ 1] 4e col 3: [ 1] 4e col 4: [ 1] 4e col 5: [ 3] 53 59 53 col 6: [ 7] 78 6e 04 0f 0e 0f 2f col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 36 col 8: [ 5] 54 41 42 4c 45 col 9: [ 7] 78 6e 04 0f 0e 0f 2f col 10: [ 3] c2 04 0c col 11: [20] 53 59 53 54 45 4d 5f 50 52 49 56 49 4c 45 47 45 5f 4d 41 50 col 12: [ 3] c2 04 0c bindmp: 2c 00 04 0a 12 cb c2 04 0c 15 cb c2 04 0c |
我们block中存的数据是345-298=47 也正是tab0中所引用的条数。
tab 0, row 0, @0x1e88
tl: 9 fb: –H-FL– lb: 0x0 cc: 6
col 0: *NULL*
col 1: [ 5] 56 41 4c 49 44
col 2: [ 1] 4e
col 3: [ 1] 4e
col 4: [ 1] 4e
col 5: [ 3] 53 59 53
bindmp: 00 03 06 ff 2d 2e 2e 2e 29
00 03 表示引用次数
06 表示列数目
ff 即为255,表示null值,这个位置是第一位,就表示col 0这一列。
2d 表示引用的第45行
后面的2e 2e 2e 29 分别表示引用了第46行数据引用了3次,引用第29行数据,引用了1次。
来看第2行的bindmp信息:
bindmp: 00 03 08 00 2c db 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34
00 03 表示被引用了3次
08 表示一共8个列
00 如果小于等于200表示行号,这是0,即是第0行。
2c 转换为10进制是44,表示引用的第44行
db 转换后是219,大于200,表示表示后面的是一列数据,其长度=219-200
32~34 这19个bytes,就是后面的一列数据。
我们可以来看下这一列数据的含义:
SQL> select hextostr(’32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 34′) from dual;
HEXTOSTR(‘323031302D30342D31353A31333A31343A3434’)
———————————————————————————————-
2010-04-15:13:14:44
我们最后再来看下最后一行数据的情况;
bindmp: 2c 00 04 0a 12 cb c2 04 0c 15 cb c2 04 0c
2c 00 表示被引用的次数。 即这行数据被应用了44次。
04 表示被引用列的列数目,即一共4个列。即有4个列被引用
0a 转换后为10,表示引用的第10行
12 表示引用的第18行
cb 转换后为203,大于200,那么减去200后等于3,表示列的长度是3,即c2 04 0c
tab 0就是压缩表特定的格式,展示的是其引用关系。 下面的tab1就是实际的block内数据。
这里以倒数第2行来举例说明:
tab 1, row 296, @0x306
tl: 30 fb: –H-FL– lb: 0x0 cc: 13
col 0: *NULL*
col 1: [ 5] 56 41 4c 49 44
col 2: [ 1] 4e
col 3: [ 1] 4e
col 4: [ 1] 4e
col 5: [ 3] 53 59 53
col 6: [ 7] 78 6e 04 0f 0e 0f 2f
col 7: [19] 32 30 31 30 2d 30 34 2d 31 35 3a 31 33 3a 31 34 3a 34 36
col 8: [ 5] 49 4e 44 45 58
col 9: [ 7] 78 6e 04 0f 0e 0f 2f
col 10: [ 3] c2 04 0b
col 11: [16] 49 5f 44 45 46 53 55 42 50 41 52 54 4c 4f 42 24
col 12: [ 3] c2 04 0b
bindmp: 2c 00 04 0a 10 cb c2 04 0b d8 49 5f 44 45 46 53 55 42 50 41 52 54 4c 4f 42 24 cb c2 04 0b
从上面看,我们知道该压缩表有13个列。
我们直接看bindmp数据:
2c 表示行头
00 表示itl槽位,我这里是0.
04 表示被压缩后的列数目,即原来13个列,被压缩后变成4个列了。
0a 表示被压缩的列的个数 转换后为10,即有10个列被压缩
10 表示对应列编号,即第10个列,从上看,其长度为3
cb 转换后是203,减去200,表示后面列长度3,后面对应的数据为:c2 04 0b
d8 转换后为216,鉴于200,表示对应的列长度是16,即其对应的数据是:c2 04 0b d8 49 5f 44 45 46 53 55 42 50 41 52 54 4c 4f 42 24
cb 转换后是203,减去200,表示后面列长度3,后面对应的数据为:c2 04 0b
关于压缩表的block结构,老熊的博客中有2篇文章描述的比较详细,大家可以参考下,熊哥是这方面的权威。
最后简单总结下:
1. 10g版本中的压缩表(实际上是9iR2引入) 的block结构跟普遍表block结构没什么差别,可以简单的理解为是block内压缩,并
实现列级别共享。block内包含2个tab信息,其中一个是符号表(重复数据,被压缩的行),另外一个tab 1是实际的data数据.
tab 0中被压缩的列都有一个bindmp指针,指向tab1中的位置。
2. 11g版本中引入了oltp compression和tablespace compression,经过测试,至少在11.2版本中oltp compression还是比较
成熟了,不过对于实际应用,还是建议进行测试,以免碰到相关bug.
3. 10g 版本中的压缩表主要适用于dss应用,而11g的oltp compression特性,显然是为了适应oltp业务而产生的。
4. 压缩表在查询上,比普通表存在优势,可以降低逻辑读等资源的消耗,甚至memory等资源.
Leave a Reply
You must be logged in to post a comment.